浅谈Java list.remove( )方法需要注意的两个坑

 更新时间:2020年12月03日 09:14:36   作者:DeMonnnnnn  
这篇文章主要介绍了浅谈Java list.remove( )方法需要注意的两个坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

list.remove

最近做项目的过程中,需要用到list.remove()方法,结果发现两个有趣的坑,经过分析后找到原因,记录一下跟大家分享一下。

代码

直接上一段代码,进行分析。

public class Main {

 public static void main(String[] args) {
  List<String> stringList = new ArrayList<>();//数据集合
  List<Integer> integerList = new ArrayList<>();//存储remove的位置

  stringList.add("a");
  stringList.add("b");
  stringList.add("c");
  stringList.add("d");
  stringList.add("e");

  integerList.add(2);
  integerList.add(4);//此处相当于要移除最后一个数据

  for (Integer i :integerList){
   stringList.remove(i);
  }

  for (String s :stringList){
   System.out.println(s);
  }
 }
}

如上代码我们有一个5个元素的list数据集合,我们要删除第2个和第4个位置的数据。

第一次运行

咦,为什么执行两次remove(),stringList的数据没有变化呢?

没有报错,说明代码没有问题,那问题出在哪呢?

仔细分析我们发现,remove()这个方法是一个重载方法,即remove(int position)和remove(object object),唯一的区别是参数类型。

  for (Integer i :integerList){
   stringList.remove(i);
  }

仔细观察上面代码你会发现,其实i是Integer对象,而由于Java系统中如果找不到准确的对象,会自动向上升级,而(int < Integer < Object),所以在调用stringList.remove(i)时,其实使用的remove(object object),而很明显stringList不存在Integer对象,自然会移除失败(0.0),Java也不会因此报错。

如果我们想使用remove(int position)方法,只能降低对象等级,即修改代码;

for (Integer i :integerList){
   int a =i;
   stringList.remove(a);
  }

第二次运行

我们发现提示在坐标为4的地方越界了,这是为什么呢?

其实很简单,因为执行stringList.remove(2)后,list.size()就-1为4了,我们原来要移除的最后一个位置的数据移动到了第3个位置上,自然就造成了越界。

我们修改代码先执行stringList.remove(4),再执行执行stringList.remove(2)。

integerList.add(4);

integerList.add(2);

这个错误提醒我们:使用remove()的方法时,要先从大到小的位置移除。当然如果你知道具体的对象,直接移除remove(对象)更稳妥。

第三次执行

嗯,这次没问题了。

总结

1、使用remove()的方法时,要先从大到小的位置移除。当然如果你知道具体的对象,直接移除remove(对象)更稳妥。

2、要密切注意自己调用的remove()方法中的,传入的是int类型还是一个对象。

补充知识: 关于List.remove()报错的问题

我们如果想删掉List中某一个对象,我们可能就会想到会用List.remove()方法。但是这样如果后续操作这个list的时候就会报错。

具体的原因是当你操作了List的remove方法的时候,他回去修改List的modCount属性。

导致抛出异常java.util.ConcurrentModificationException。

最好的想要修改List对象,我们可以用ListIterator。

就像这样:

ArrayList<Integer> arrayList = new ArrayList<>();
 for (int i = 0; i < 20; i++) {
 arrayList.add(Integer.valueOf(i));
 }

ListIterator<Integer> iterator = arrayList.listIterator();

while (iterator.hasNext()) {
if(需要满足的条件){
iterator.remove();//删除操作
iterator.add(integer);//新增操作

}
}

这样就不会去修改List的modCount属性。

以上这篇浅谈Java list.remove( )方法需要注意的两个坑就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringMVC bean实现加载控制方法详解

    SpringMVC bean实现加载控制方法详解

    SpringMVC是一种基于Java,实现了Web MVC设计模式,请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将Web层进行职责解耦。基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,SpringMVC也是要简化我们日常Web开发
    2022-08-08
  • Java实现合并word文档的示例代码

    Java实现合并word文档的示例代码

    在做项目中,经常会遇到一种情况,需要将一个小word文档的内容插入到一个大word(主文档)中。本文就为大家准备了Java实现合并word文档的方法,需要的可以参考一下
    2022-08-08
  • mybatis 使用concat 模糊查询方式

    mybatis 使用concat 模糊查询方式

    这篇文章主要介绍了mybatis 使用concat 模糊查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • 多层嵌套的json的值如何解析/替换

    多层嵌套的json的值如何解析/替换

    这篇文章主要介绍了多层嵌套的json的值如何解析/替换的方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • 正确遍历删除List中的元素方法(推荐)

    正确遍历删除List中的元素方法(推荐)

    下面小编就为大家带来一篇正确遍历删除List中的元素方法(推荐)。小编觉得挺不错的,在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • Java empty、null、blank的区别小结

    Java empty、null、blank的区别小结

    本文主要介绍了Java empty、null、blank的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 三种Java求最大值的方法

    三种Java求最大值的方法

    本篇文章给大家总结了在JAVA中求最大值的三种常用方法,以及代码做了分享,需要的朋友参考下。
    2018-02-02
  • 浅谈Java内存泄露

    浅谈Java内存泄露

    内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。下面我们来一起了解如何解决
    2019-05-05
  • Java使用Request获取请求参数的通用方式详解

    Java使用Request获取请求参数的通用方式详解

    这篇文章主要给大家介绍了关于Java使用Request获取请求参数的通用方式,在Java后端开发中第一步就是获取前端传过来的请求参数,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • java swing中实现拖拽功能示例

    java swing中实现拖拽功能示例

    这篇文章主要介绍了java swing中实现拖拽功能示例,需要的朋友可以参考下
    2014-04-04

最新评论