Arrays.asList的坑

简介:

将一个数组转换为 List 以便进行更丰富的操作

坑一: 将原生数据类型数据的数组作为参数

public class Main {
    public static void main(String[] args) {
      int[] test = new int[]{1,2,3,4};
      List list = Arrays.asList(test);
        System.out.println(list.size());
        System.out.println(list);
/*
1
[[I@45ee12a7]
*/
    }
}

尝试使用IDEA自动修复看看它传入的类型:居然是int[]



也就是说T是数组元素的 class
如果你对反射技术比较了解的话,那么 class 的含义想必是不言自明。我们知道任何类型的对象都有一个 class 属性,这个属性代表了这个类型本身。原生数据类型,比如 int,short,long等,是没有这个属性的,具有 class 属性的是它们所对应的包装类 Integer,Short,Long。
  因此,这个错误产生的原因可解释为:asList 方法的参数必须是对象或者对象数组,而原生数据类型不是对象——这也正是包装类出现的一个主要原因。当传入一个原生数据类型数组时,asList 的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组。
解决方案:使用包装类数组或使用流转换为List

1.
public class Main {
    public static void main(String[] args) {
      Integer[] test = new Integer[]{1,2,3,4};
      List list = Arrays.asList(test);
        System.out.println(list.size());
        System.out.println(list);
/*
4
[1, 2, 3, 4]
*/
    }
}

2.
public class Main {
    public static void main(String[] args) {
      int[] test = new int[]{1,2,3,4};
//Java 8 新引入的 Stream 操作 要将一个原始类型流转换成一个对象流,可以使用boxed方法
        List myList = Arrays.stream(test).boxed().collect(Collectors.toList());
        System.out.println(myList.size());
        System.out.println(myList);
/*
4
[1, 2, 3, 4]
*/
    }
}

坑二:试图修改 List 的大小

public class Main {
    public static void main(String[] args) {
      Integer[] test = new Integer[]{1,2,3,4};
      List list = Arrays.asList(test);
      Integer a = new Integer(1);
      list.add(a);
//Exception in thread "main" java.lang.UnsupportedOperationException
    }
}

直接报错
向 list 添加新元素是不被允许的;
如果试图从 myList 中删除元素,也会抛出相同的异常。为什么会如此?
官方指出有一句话:
Arrays.asList返回一个由指定数组生成的固定大小的 List。
查看相关的源码


方法中的的确确生成了一个 ArrayList 再点进去看

有一个被声明为 final 的数组 a ,所有传入的元素都会被保存在这个数组 a 中。到此,谜底又揭晓了: asList 方法返回的确实是一个 ArrayList ,但这个 ArrayList 并不是 java.util.ArrayList ,而是 java.util.Arrays 的一个内部类。这个内部类用一个 final 数组来保存元素,因此用 asList 方法产生的 ArrayList 是不可修改大小的。这里记住最后是一个final数组保存的元素
与下面final修饰区分

final List list1 = new ArrayList<>();
list1.add(new Integer(1));
list1.add(new Integer(2));
System.out.println(list1);
//[1,2]

解决方案:创建一个真正的 ArrayList

Integer[] test = new Integer[]{1,2,3,4};
List list = new ArrayList(Arrays.asList(test));
list.add(new Integer(5));
System.out.println(list);
//[1, 2, 3, 4, 5]

参考文章
https://www.jianshu.com/p/2b113f487e5e

你可能感兴趣的:(Arrays.asList的坑)