java - 为什么 ArrayList 中的 retainAll 抛出异常

标签 java

我已经使用 subList 方法创建了一个新的 ArrayList。现在,当我尝试使用 retainAll 执行交集操作时,它会抛出以下异常

retainAll() 方法适用于下面的代码

List<Integer> arrNums1 = new ArrayList<Integer>();
arrNums1.add(1);
arrNums1.add(2);
arrNums1.add(3);

List<Integer> arrNums2 = arrNums1.subList(0, 1);
arrNums2.retainAll(arrNums1);

但是当我尝试为下面的代码应用 retainAll 时,它会生成如下异常

Java 代码

public class Generics1
{   
 public static void main(String[] args)
 {
       List<Fruits> arrFruits = new ArrayList<Fruits>();

        Fruits objApple  = new Apple();
        Fruits objOrange = new Orange();
        Fruits objMango  = new Mango();

        arrFruits.add(objApple);
        arrFruits.add(objOrange);
        arrFruits.add(objMango);

        List<Fruits> arrNewFruits = arrFruits.subList(0, 1);

        System.out.println(arrFruits.retainAll(arrNewFruits));
  }
}

class Fruits {}

class Apple extends Fruits {}

class Orange extends Fruits {}

class Mango extends Fruits {}

错误

enter image description here

最佳答案

当您使用 List#subList() 时:

Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.

您可以改变其中的元素,但不能更改列表的结构。

文档进一步说:

The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)

retainAll() 函数使用迭代器删除不相交的值,这会导致 ConcurrentModificationException。注意 documenation 是什么说:

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception.

复制List,然后执行retainAll():

List<Fruits> arrNewFruits = new ArrayList<>(arrFruits.subList(0, 1));

关于java - 为什么 ArrayList 中的 retainAll 抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17564434/

相关文章:

java - 在 1 行上动态加载 5 个按钮

java - 如何使用 Swing 应用程序配置 spring-boot

java - 如何在Java中解析 "dateTime.tz"

java - 当元素不区分大小写时,是否可以使用单个 Xpath 表达式扫描 xml 元素

java - JNI获取ConcurrentHashMap

java - Esper:获取监听器更新方法内语句的名称/用户对象

java - 将音频从 PC 流式传输到智能手机?

java - 可以为每个 Actor 指定自定义路由或自定义构造函数参数

java - Selenium 网络驱动程序 : How to select the dynamically generated button by taking the reference of previuos tag's xpath

java - 在 Java 中获取受支持的 CPU 功能/指令