美文网首页Android文章
通过Arrays.asList方法将数组转成集合后,能否修改集合

通过Arrays.asList方法将数组转成集合后,能否修改集合

作者: 爱读书的顾先生 | 来源:发表于2019-01-28 09:20 被阅读1809次
    人生一切难题,知识给你答案

    温馨提示:阅读本文需要3-4分钟(少量代码)


    今天,我们来解决一个问题:

    通过Arrays.asList方法将数组转成集合后,能否修改集合个数?

    人生一切难题,知识给你答案。


    数组与集合都是用来存储对象的容器,两者之间可以进行相互转换,数组转集合可以通过Arrays.asList方法。

    ==Arrays.asList==

    通过Arrays.asList方法将数组转成集合后,能否修改集合个数?针对这个问题,我们直接给出例子:

    public class Demo {
        public static void main(String[] args){
            String[] strings={"A","B","C"};
            List<String> stringList=Arrays.asList(strings);
    
            stringList.set(0,"G");
            System.out.println(strings[0]);
    
            stringList.add("M");
        }
    }
    

    运行结果:

    G
    Exception in thread "main" java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:148)
        at java.util.AbstractList.add(AbstractList.java:108)
        ...
    

    通过上面的例子可以发现通过set()方法修改元素的值,原有数组相应位置的值也被修改了,说明修改值没有问题,接着通过调用add()方法直接抛出UnsupportedOperationException异常,说明不能进行修改元素个数的任何操作。

    那为什么不能修改元素个数呢?进入Arrays.asList源码中查看:

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

    发现直接创建了一个ArrayList对象,按照我们平时对ArrayList的理解,应该可以修改元素个数啊?原来这个ArrayList不是我们平时使用的那个ArrayList,它是Arrays的静态内部类ArrayList。

    public class Arrays {
        ...
        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) {
                ...
            }
    
            @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) {
                ...
            }
    
            @Override
            public boolean contains(Object o) {
                ...
            }
    
            @Override
            public Spliterator<E> spliterator() {
                ...
            }
    
            @Override
            public void forEach(Consumer<? super E> action) {
                ...
            }
    
            @Override
            public void replaceAll(UnaryOperator<E> operator) {
                ...
            }
    
            @Override
            public void sort(Comparator<? super E> c) {
                ...
            }
        }
        ...
    }
    

    Arrays的静态内部类ArrayList中,set方法本质还是对数组进行值的修改操作,并且静态内部类ArrayList内部没有实现类似add、remove、clear相关方法,所以调用修改元素个数的相关方法时会抛出UnsupportedOperationException异常。

    还有一个问题,我们在上面案例中通过set方法修改了ArrayList集合的第一个元素的值,在我们访问原有数组的第一个位置时,值也被改变了,这是为什么呢?

    public class Arrays {
        ...
        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);
            }
    
            ...
        }
        ...
    }
    

    静态内部类ArrayList的成员变量a使用了final,用于存储集合的数组引用始终被强制指向原有数组。

    因此,通过Arrays.asList方法将数组转换成集合后,避免修改元素的个数,否则会引发异常。


    838794-506ddad529df4cd4.webp.jpg

    相关文章

      网友评论

        本文标题:通过Arrays.asList方法将数组转成集合后,能否修改集合

        本文链接:https://www.haomeiwen.com/subject/zwiojqtx.html