一般数组转集合的方法是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() 的注意事项 :
- 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));
运行结果
- 使用集合的修改方法: 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 ?
- 最简单的方法
List list = new ArrayList<>(Arrays.asList("a", "b", "c"))
- 使用 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