Arrays.asList返回的List不支持add/remove操作原理及解决方法

文章目录

    • 问题描述
    • 原理
    • 解决方法

问题描述

Arrays.asList返回的集合不支持元素的添加和删除。也就是不可以使用add、addAll和remove操作。
有时候经常需要把一个数组转换成List进行操作
大家常常都会使用Arrays的静态方法asList。
比如这样 List list = Arrays.asList(“a”, “b”, “c”);
然后经常就直接对集合进行元素的添加、删除操作了。
但是这样是不可以的,为什么不可以?
那我们试验一下看看会发生什么?

问题复现:

import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args){
        List<String> list = Arrays.asList("a","b","c");
        list.add("d");
        System.out.println(list);
    }
}

运行结果:

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at com.demo.controller.Test.main(Test.java:10)

结论:直接对Arrays.asList返回的集合进行添加、移除操作会抛出UnsupportedOperationException异常

原理

查看源码发现Arrays类静态方法asList函数返回值类型是Arrays自定义的内部类。源码如下:

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
        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;
        }

        ......省略其他方法......

然后再看看,该内部类ArrayList继承了AbstractList但未重写父抽象类里面的add、addAll和remove方法。所以调用add、addAll、remove方法实际上是调用了父类AbstractList中的方法。查看AbstractList发现这几个都未具体实现,直接返回了不支持操作异常即UnsupportedOperationException

public void add(int index, E element) {
   throw new UnsupportedOperationException(); //add方法抛出UnsupportedOperationException异常
}

public boolean add(E e) {
   add(size(), e);//调用add方法然后抛出异常
    return true;
}

public E remove(int index) {
   throw new UnsupportedOperationException();//抛出异常
}

public boolean addAll(int index, Collection<? extends E> c) {
    rangeCheckForAdd(index);
    boolean modified = false;
    for (E e : c) {
        add(index++, e);//调用add方法然后抛出异常
        modified = true;
    }
    return modified;
}

public void add(int index, E element) {
   throw new UnsupportedOperationException();
}

解决方法

解决方法:使用addAll方法将Arrays.asList返回的List添加到已实例化的List中

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args){
        List<String> list = Arrays.asList("a","b","c");
        List<String> list1 = new ArrayList<>();
        list1.addAll(list);
        list1.add("d");//对已实例化的list可以进行add, remove等操作
        System.out.println(list1); //[a, b, c, d]
    }
}

你可能感兴趣的:(java,java)