数组转集合

135 阅读1分钟

一般数组转集合的方法是Arrays.asList() ,可以使用它将一个数组转换为一个 List 集合。

String[] myArray = {"A", "B", "C"};
List<String> myList = Arrays.asList(myArray);
//上面两个语句等价于下面一条语句
List<String> myList = Arrays.asList("A", "B", "C");

asList() 源码如下:

/**
*返回指定数组支持的固定大小的列表。(更改返回列表“透写”到数组。)这个方法与Collection.toArray结合使用,充当了基于数组和基于集合的api之间的桥梁。返回的列表是可序列化的,并实现了RandomAccess。
*该方法还提供了一种方便的方法来创建一个固定大小的列表,初始化后包含以下几个元素:
*List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");    
*Params: a -列表将被支持的数组
*Returns:指定数组的列表视图
*/
@SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

使用 Arrays.asList() 注意事项

  1. Arrays.asList()是泛型方法,传递的数组必须是对象数组,而不是基本类型。

通过对源码的分析就可以看出来传入的是泛型方法,当传入需要转化的数组时得到的不是数组里面的每一个元素,而是数组本身。

int[] myArray = {1, 2, 3};
List myList = Arrays.asList(myArray);
System.out.println(myList.size());//1
System.out.println(myList.get(0));//数组地址值
System.out.println(myList.get(1));//报错:ArrayIndexOutOfBoundsException

运行结果:

当你这样写的时候编译软件会提醒这个问题(idea 2023.3.1

既然出现了这种问题应该怎么解决呢?

使用包装类就可以解决这个问题,因为包装类传入的是一个个对象。

Integer[] myArray = {1, 2, 3};
List myList = Arrays.asList(myArray);
System.out.println(myList.size());//1
System.out.println(myList.get(0));
System.out.println(myList.get(1));
System.out.println(myList.get(2));

运行结果

  1. 使用集合的修改方法: add()、remove()、clear()会抛出异常。

《阿里巴巴 Java 开发手册》的描述如下:

使用工具类 Arrays.asList() 把数组转换成集合时,不能使用其修改集合相关的方法, 它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

实例如下:

    public static void main(String[] args) {
        String[] myArray = {"A", "B", "C"};
        List<String> myList = Arrays.asList(myArray);
        List<String> list = Arrays.asList(myArray);
        list.add("D");
    }

为什么会出现这种情况呢?

Arrays.asList()得到的返回值不是java.util.ArrayList而是java.util.Arrays$ArrayList java.util.Arrays的一个内部类,其中重写实现add()、remove()、clear() 方法,所以当你调用的时候就是不支持的操纵。

我们再看一下java.util.AbstractList的 add/remove/clear 方法。

public E remove(int index) {
    throw new UnsupportedOperationException();
}
public boolean add(E e) {
    add(size(), e);
    return true;
}
public void add(int index, E element) {
    throw new UnsupportedOperationException();
}

public void clear() {
    removeRange(0, size());
}
protected void removeRange(int fromIndex, int toIndex) {
    ListIterator<E> it = listIterator(fromIndex);
    for (int i=0, n=toIndex-fromIndex; i<n; i++) {
        it.next();
        it.remove();
    }
}

既然如此,那我们如何正确的将数组转换为 ArrayList ?

  1. 最简单的方法
List list = new ArrayList<>(Arrays.asList("a", "b", "c"))
  1. 使用 Java8 的 Stream (推荐)
Integer [] myArray = { 1, 2, 3 };
List myList = Arrays.stream(myArray).collect(Collectors.toList());
//基本类型也可以实现转换(依赖boxed的装箱操作)
int [] myArray2 = { 1, 2, 3 };
List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());

当然还有一些其它的方法,就不一一罗列了。

参考文章:

原文链接:https://javaguide.cn/java/collection/java-collection-precautions-for-use.html