ArrayList retainAll让我很困惑

时间:2018-04-13 09:35:37

标签: java

我正在尝试使用java中的交叉点。如果我有以下内容,我只想要一个没有任何内容的arraylist,因为交集给我零。

List<String> coll1 = Arrays.asList(["A"]);
List<String> coll2 = Arrays.asList(["B","C"]);

coll1.retainAll(coll2);

但是retainAll抛出此异常:

java.lang.UnsupportedOperationException
    at java.util.AbstractList.remove(AbstractList.java:161)
    at java.util.AbstractList$Itr.remove(AbstractList.java:374)
    at java.util.AbstractCollection.retainAll(AbstractCollection.java:410)

如果我将列表转换为集合,那么如果我调用retainAll,我会得到一个空的集合:

Set<String> set1 = new HashSet<String>(coll1);
Set<String> set2 = new HashSet<String>(coll2);

set1.retainAll(set2); //gives me an empty set, which is good!

为什么ArrayList有空交叉点的问题?

2 个答案:

答案 0 :(得分:5)

这是因为Arrays.asList创建了一个不可变列表,所以当你调用retainAll试图从它所抱怨的列表中删除条目时。

解决方案是创建一个新的ArrayList副本。

public void test(String[] args) {
    List<String> coll1 = new ArrayList<>(Arrays.asList("A"));
    List<String> coll2 = new ArrayList<>(Arrays.asList("B","C"));
    coll1.retainAll(coll2);
    System.out.println(coll1);
}

打印:

  

[]

答案 1 :(得分:2)

在您的代码中,并在您的答案中解释,您没有显式使用ArrayList而是使用AbstractList。正如doc

中的解释
  

<强>抛出:    UnsupportedOperationException - 如果此集合不支持retainAll操作

由于您没有显式声明ArrayList,因此您没有使用ArrayList,而是使用未实现retainAll的AbstractList,因此它会抛出此异常。

将List声明为ArrayList,它应该没问题

List<String> list1 = new ArrayList<String>();