• Java集合List报错,java.lang.UnsupportedOperationException


    在这里插入图片描述

    大家好,我是哪吒。

    今天在review代码的时候,发现一个同事的是这样写的。

    public static void main(String[] args) {
        String[] arr = {"哪吒编程", "study", "java"};
        List<String> list = Arrays.asList(arr);
        System.out.println(list);
        list.add("study python");
        System.out.println(list);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    打眼没看出问题,一般不都这样写嘛,但是…

    难道学位java,就不能学习Python了吗?

    在这里插入图片描述

    一、点击Arrays.asList源码,一探究竟

    asList()方法返回的ArrayList,不是大家常用的java.util.ArrayList,而是Arrays的静态内部类ArrayList。

    Arrays的静态内部类ArrayList中,并没有重写AbstractList的add方法。

        public static <T> List<T> asList(T... a) {
            return new ArrayList<>(a);
        }
    
        /**
         * @serial include
         */
        private static class ArrayList<E> extends AbstractList<E>
            implements RandomAccess, java.io.Serializable
        {
            private static final long serialVersionUID = -2764017481108945198L;
            private final E[] a;
    
            ArrayList(E[] array) {
                a = Objects.requireNonNull(array);
            }
    
            @Override
            public int size() {
                return a.length;
            }
    
            @Override
            public Object[] toArray() {
                return a.clone();
            }
    
            @Override
            @SuppressWarnings("unchecked")
            public <T> T[] toArray(T[] a) {
                int size = size();
                if (a.length < size)
                    return Arrays.copyOf(this.a, size,
                                         (Class<? extends T[]>) a.getClass());
                System.arraycopy(this.a, 0, a, 0, size);
                if (a.length > size)
                    a[size] = null;
                return a;
            }
    
            @Override
            public E get(int index) {
                return a[index];
            }
    
            @Override
            public E set(int index, E element) {
                E oldValue = a[index];
                a[index] = element;
                return oldValue;
            }
    
            @Override
            public int indexOf(Object o) {
                E[] a = this.a;
                if (o == null) {
                    for (int i = 0; i < a.length; i++)
                        if (a[i] == null)
                            return i;
                } else {
                    for (int i = 0; i < a.length; i++)
                        if (o.equals(a[i]))
                            return i;
                }
                return -1;
            }
    
            @Override
            public boolean contains(Object o) {
                return indexOf(o) != -1;
            }
    
            @Override
            public Spliterator<E> spliterator() {
                return Spliterators.spliterator(a, Spliterator.ORDERED);
            }
    
            @Override
            public void forEach(Consumer<? super E> action) {
                Objects.requireNonNull(action);
                for (E e : a) {
                    action.accept(e);
                }
            }
    
            @Override
            public void replaceAll(UnaryOperator<E> operator) {
                Objects.requireNonNull(operator);
                E[] a = this.a;
                for (int i = 0; i < a.length; i++) {
                    a[i] = operator.apply(a[i]);
                }
            }
    
            @Override
            public void sort(Comparator<? super E> c) {
                Arrays.sort(a, c);
            }
        }
    	...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

    那么,重写过的就好用了呗?试一下哈,果然是可以的,以后一定要多读读源码,源码很重要~

    在这里插入图片描述

    二、习惯了Arrays.asList,就是想用.add()添加元素,怎么办?

    其实也很简单:

    public static void main(String[] args) {
        String[] arr = {"哪吒编程", "study", "java"};
        List<String> list = new ArrayList(Arrays.asList(arr));
        list.add("study python");
        System.out.println(list); //[哪吒编程, study, java, study python]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三、又有一个同事,是这样写的

    public static void main(String[] args) {
        String[] arr = {"哪吒编程", "study", "java"};
        List<String> list = Arrays.asList(arr);
        arr[2] = "python";
        System.out.println(list);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    你猜猜,上面的代码会输出啥?

    在这里插入图片描述

    也就是说,对数组的修改会修改list的内容。

    四、重新点击Arrays.asList源码,一探究竟

    不好意思,关早了,哈哈。

    asList中创建了 ArrayList,但是他直接引用了原本的数组对象。所以只要原本的数组对象一发生变化,List也跟着变化

    public static <T> List<T> asList(T... a) {
          return new ArrayList<>(a);
      }
    
      ArrayList(E[] array) {
          a = Objects.requireNonNull(array);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    五、全是坑,怎么办?

    一个一个填呗,没办法啊。再new一个,轻松解决。

    虽然很简单,也很基础,但实际开发中,全图速度,太少人会注意这些了。

    写完代码,摸摸鱼,不香吗?

    public static void main(String[] args) {
        String[] arr = {"哪吒编程", "study", "java"};
        List<String> list = Arrays.asList(arr);
        List<String> list2 = new ArrayList<>();
        list2.addAll(list);
        arr[2] = "python";
        System.out.println(list);// [哪吒编程, study, python]
        System.out.println(list2);// [哪吒编程, study, java]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师

  • 相关阅读:
    IDEA中如果优雅Debug
    工业级ADSL有线路由器/远程视频监控专用路由器
    案例:如何评价代码走查的效果?
    智慧图书馆中一般有哪些设备
    postman接口测试中文汉化教程
    D-Wave 推出快速退火功能,扩大量子计算性能增益
    python 装饰器
    Go Web项目 接口开发全流程
    掌握Spring条件装配的秘密武器
    SpringMVC 异常处理器
  • 原文地址:https://blog.csdn.net/guorui_java/article/details/133496496