列表 retainAll 异常

10

我想测试如何获取两个列表的交集,这是我的代码:

            List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);
        List<Integer> list2 = list.subList(2, 5);

        System.out.println(list.subList(2, 5));
        System.out.println(list.containsAll(list.subList(2, 5)));
        System.out.println(list.retainAll(list2));

这将产生:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.remove(Unknown Source)
    at java.util.AbstractList$Itr.remove(Unknown Source)
    at java.util.AbstractCollection.retainAll(Unknown Source)
    at gov.noaa.nhc.App.main(App.java:48)

但我并没有执行任何删除操作。为什么会出现异常?

更新 I:

使用:

List<Integer> list = new ArrayList<Integer>(Arrays.asList(16, 17, 18, 19, 20));
List<Integer> list2 = list.subList(2, 5);

生成:

java.util.ConcurrentModificationException

由于list2是由list1支持的,因此从list1中删除项目会导致此异常。最终工作版本:

List<Integer> list = new ArrayList<Integer>(Arrays.asList(16, 17, 18, 19, 20));
List<Integer> list2 = Arrays.asList(18, 19, 20);
或者
List<Integer> list = new ArrayList<Integer>(Arrays.asList(16, 17, 18, 19, 20));
List<Integer> list2 = new ArrayList<Integer>(Arrays.asList(18, 19, 20));
或者
 List<Integer> list = new ArrayList<Integer>(Arrays.asList(16, 17, 18, 19, 20));
 List<Integer> list2 = new ArrayList<Integer>(list.subList(2, 5));

大家的回答都很感谢。

5个回答

28

使用 Arrays.asList 方法时,你会得到一个由传入的实际数组支持的列表,但功能受到限制。如果你想要一个完全可修改的列表,必须创建一个新列表。例如:

List<Integer> list = new ArrayList<Integer>(Arrays.asList(16, 17, 18, 19, 20));
List<Integer> list2 = new ArrayList<Integer>(list.subList(2, 5));
list.retainAll(list2);
System.out.println(list);
// result: [18, 19, 20]

如果此集合不支持retainAll操作,则会抛出UnsupportedOperationException异常。 - user845279
使用您的示例,我得到了“主线程中的异常”java.util.ConcurrentModificationException。 - Gandalf StormCrow
这是因为您使用了 subList() 函数。list2 是由 list 支持的。retainAll 函数使用迭代器来删除非交集值 - 这会导致 ConcurrentModificationException。您可以在 Javadocs 上阅读有关 Iterator 和并发修改的内容。 - user845279
1
一个解决方案是:List<Integer> list2 = new ArrayList<Integer>(list.subList(2, 5)); - user845279
更新答案以避免“ConcurrentModificationException”。 - ataylor
为什么会得到那个结果?我本来以为结果是 [ ]。retainAll:仅保留此列表(list)中包含在指定集合(list2)中的元素。 - Fernando Pie

3
根据文档List.retainAll() 方法仅保留与指定集合中相同的元素(可选操作)。换言之,从此列表中删除不在指定集合中的所有元素。需要注意的是,强调的是要删除不属于指定集合中的元素。

1

retainAll并不会从被调用的列表中移除任何项目。


0

retainAll 只保留给定列表中存在的所有元素。


0

文档还指出,当列表实现不支持此方法时,retainAll会抛出UnsupportedOperationException异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接