我已经使用 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 {}
错误
最佳答案
当您使用 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/