Java中ArrayList remove会遇到的坑

简介: 前言平时最常用的莫过于ArrayList和HashMap了,面试的时候也是问答的常客。先不去管容量、负载因子什么的,就是简单的使用也会遇到坑。Remove 元素经常遇到的一个场景是:遍历list, 然后找到合适条件的给删除掉,比如删除所有的偶数。

前言

平时最常用的莫过于ArrayListHashMap了,面试的时候也是问答的常客。先不去管容量、负载因子什么的,就是简单的使用也会遇到坑。
img_fa1bace04e96fa472c3c9dad1823d7d3.jpg

Remove 元素

经常遇到的一个场景是:遍历list, 然后找到合适条件的给删除掉,比如删除所有的偶数。

@Test
public void testRemove2(){
    List<Integer> integers = new ArrayList<>(5);
    integers.add(1);
    integers.add(2);
    integers.add(2);
    integers.add(4);
    integers.add(5);

    for (int i = 0; i < integers.size(); i++) {
        if (integers.get(i)%2==0){
            integers.remove(i);
        }
    }

    System.out.println(integers);
}

看起来好像没问题,加入面试的时候当面问:输出结果是什么?再问真不会报错吗?再问结果是什么?

  • 报错
  • 结果是空list
  • 结果是[1, 2, 5]

List.remove()有两个,一个public E remove(int index),一个是public boolean remove(Object o),那下面的结果是什么:

@Test
public void testRemove(){
    ArrayList<Integer> integers = Lists.newArrayList(1, 2, 3, 4);
    System.out.println(integers);
    integers.remove(1);
    System.out.println(integers);
}
  • [1, 3, 4]

经常会使用一个Arrays.asList的API, 那么下面的结果是什么:

@Test
public void testRemove3(){
    List<String> list = Arrays.asList("a","b");
    list.add("c");
    System.out.println(list);
}
  • 报错: java.lang.UnsupportedOperationException

使用foreach是否可以实现刚开始的问题

@Test
public void testRemove4(){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    for (String string : strings) {
        strings.remove(string);
    }
}
  • 否,报错java.util.ConcurrentModificationException

为了性能问题,我们推荐把list.size的计算提取出来

@Test
public void testRemove5(){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    int size = strings.size();
    for (int i = 0; i < size; i++) {
        strings.remove(i);
    }

}
  • 报错: java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
  • 这是很好的习惯, 不像开头那样每次循环都计算一次size,而且按这种情况还可以再运行的时候报错。文初的做法不报错,但结果并不是我们想要的。

使用Iterator是不是就可以remove了


@Test
public void testRemove6(){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    Iterator<String> iterator = strings.iterator();
    while (iterator.hasNext()){
        String next = iterator.next();
        strings.remove(next);
    }

    System.out.println(strings);
}
  • 报错: java.util.ConcurrentModificationException

正确的remove做法是什么

@Test
public void testRemove7(){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    Iterator<String> iterator = strings.iterator();
    while (iterator.hasNext()){
        String next = iterator.next();
        iterator.remove();
    }

    System.out.println(strings);
}




唯有不断学习方能改变! -- Ryan Miao
目录
相关文章
|
4月前
|
算法 Java C++
Java之List
Java之List
30 0
|
9月前
|
存储 安全 Java
java 集合list
当涉及到在 Java 中管理和操作多个元素时,`List` 是一个不可或缺的工具。作为 Java 集合框架中的一部分,`List` 提供了一种有序、可重复的数据存储方式,为开发人员提供了强大的功能。在本文中,我们将深入探讨 Java 中的 `List` 接口,了解其常见实现类以及如何高效地使用它们。
|
10月前
|
存储 Java
【Java】ArrayList集合
【Java】ArrayList集合
37 0
|
10月前
|
存储 算法 Java
Java—List接口(ArrayList)
今天来看看Java集合中的List集合,为什么List集合中元素能重复?为什么List集合是有序的?我们来共同交流交流
|
10月前
|
存储 算法 Java
java-List
java-List
62 0
|
11月前
|
存储 Java 索引
java Arraylist集合
数组的长度不可以发生改变。 但是ArrayList集合的长度是可以随意变化的。 对于ArrayList来说,有一个尖括号<E>代表泛型。 泛型:也就是装在集合当中的所有元素,全都是统一的什么类型。 注意:泛型只能是引用类型,不能是基本类型。 注意事项: 对于ArrayList集合来说,直接打印得到的不是地址值,而是内容。如果内 容是空,得到的是空的中括号:[] ArrayList当中的常用方法有: public boolean add(Ee):向集合当中添加元素,参数的类型和泛型一致。返回值代表添加是否成功。 备注:对于ArrayList集合来说,add添加动作一定是成功的,所以返回值可
50 0
|
存储 Java 索引
Java中的集合1——ArrayList
Java中的集合1——ArrayList
88 0
Java中的集合1——ArrayList
|
Java C++ 索引
List的使用(Java)
顺序表是Java实际开发中用到的最多的数据结构之一。
97 0
List的使用(Java)
|
存储 安全 Java
Java中的List
Java中的List
|
Java
java8 list转map
java8 list转map,list集合中的元素的属性转set,list集合中对象的属性转list,list 排序,list分组...
112 0