• 【记录】Java两个集合取交集出现UnsupportedOperationException


    我们知道,Java 的两个集合取交集操作使用的是 retainAll() 方法,然而我在取交集时却遇到了 UnsupportedOperationException 异常,是怎么回事呢?

    代码是这样的:

    1. @SpringBootTest
    2. class SpringbootStudyApplicationTests {
    3. @Test
    4. void test0730(){
    5. String [] arr = {"1111","2222","3333","4444","5555"};
    6. List listA = Arrays.asList(arr);
    7. List listB = new ArrayList<>();
    8. listB.add("1111");
    9. listB.add("3333");
    10. // listA对listB取交集
    11. listA.retainAll(listB);
    12. System.out.println(listA);
    13. }
    14. }

    运行之后,报出以下异常:

     按照打印的异常信息,找到 AbstractCollection.retainAll() 方法,源码如下:

    1. public boolean retainAll(Collection c) {
    2. Objects.requireNonNull(c);
    3. boolean modified = false;
    4. Iterator it = iterator();
    5. while (it.hasNext()) {
    6. if (!c.contains(it.next())) {
    7. it.remove();
    8. modified = true;
    9. }
    10. }
    11. return modified;
    12. }
    13. default void remove() {
    14. throw new UnsupportedOperationException("remove");
    15. }

    请注意,该方法上有一段注释说明:Note that this implementation will throw an UnsupportedOperationException if the iterator returned by the iterator method does not implement the remove method and this collection contains one or more elements not present in the specified collection. 也就是说,iterator() 方法返回的迭代器未实现 remove() 方法,并且此集合包含指定集合中不存在的一个或多个元素,则此实现将引发 UnsupportedOperationException 异常

    到这里似乎明白了什么,迭代器未实现 remove() 方法?那需要继续看下 Arrays.asList() :

    1. public static List asList(T... a) {
    2. return new ArrayList<>(a);
    3. }

    额,Arrays 的内部类 ArrayList 集合确实没有 remove() 方法,也没有 retainAll() 方法,如下:

    那么问题来了,为什么使用 new ArrayList(); 的 ArrayList 集合却没问题呢?打开 ArrayList 集合源码看一眼也就明白了:

    至此,这个问题的原因就找到了。为了避免这种坑,我们应该正确使用 List 集合,把开始的代码改造成这样就没问题了:

    1. @SpringBootTest
    2. class SpringbootStudyApplicationTests {
    3. @Test
    4. void test0730(){
    5. String [] arr = {"1111","2222","3333","4444","5555"};
    6. List listA = new ArrayList<>(Arrays.asList(arr));
    7. List listB = new ArrayList<>();
    8. listB.add("1111");
    9. listB.add("3333");
    10. // listA对listB取交集
    11. listA.retainAll(listB);
    12. System.out.println(listA);
    13. }
    14. }

    在此记录一下~

  • 相关阅读:
    Html5+CSS3+JS代码实现动态圣诞树
    前缀和 LeetCode1094 拼车
    卷积神经网络的训练过程,卷积神经网络如何训练
    中关村科幻产业创新中心 “科技赋能文化旅游,洞见哈萨克斯坦”数字旅游展盛大开幕
    Redis高级
    [学习笔记]CS224W
    【数据结构】栈和队列
    Linux 文件权限详细教程
    HTML静态网页成品作业(HTML+CSS)——家乡泉州介绍网页(3个页面)(表格布局)
    SPA项目开发之登陆注册
  • 原文地址:https://blog.csdn.net/qq_29119581/article/details/126078083