Arrays.asList类型转换结果的坑
文章目录
在各种Java
编程规范中都强调尽量不用java.util.Arrays.asList()方法以避免调用此方法生成的List
无法进行修改操作,个人近期在使用过程中发现该方法的另外一个坑,简单记录下。
问题描述
在程序中需要检测某个元素是否在数组中,处于缩短代码篇幅的考虑,自己采用了Arrays.asList
方法将其转化为List
然后调用contains
方法来判断:
public static boolean checkContains(int ele) {
int[] data = {11, 12, 13, 14};
return Arrays.asList(data).contains(ele);
}
但实际执行结果和自己预期的不一致,理论上的结果应该为true
,而实际返回的结果为false
问题分析
在Debug模式下查看Arrays.asList(data)
返回的值,发现其返回的结果不是预期中的List<Integer>
而是List<int[]>
,从而导致调用List.contains()
方法失效!
在IDEA中将Arrays.asList(data)
返回的结果单独赋值给一个变量,可发现其类型确实为List<int[]>
,若将结果类型修改为List<Integer>
则会报错,如下图所示:
在上图右边的报错信息中有如下说明信息:
no instance(s) of type variable(s) exist so that int[] conforms to Integer inference variable T has incompatible bounds: equality constraints: Integer lower bounds: int[]
上述文字的核心内容为Arrays.asList
需要获取Object
类型,而int
是原生类型,但int[]
符合要求,因此Arrays.asList()
方法会将原始的int
数组视作一个int[]
对象进行处理,从而导致此结果1。
解决方案
找到问题原因后修改起来也很容易,按照通常的编程习惯,只需要把数组的定义从int
修改为Integer
即可
public static boolean checkContains(int ele) {
Integer[] data = {11, 12, 13, 14};
List<Integer> dataList = Arrays.asList(data);
return dataList.contains(ele);
}
执行结果符合预期
Update:
在Stackoverflow
上找到一个类似问题2,在其回答中提供了一些其它实现方案:
-
JDK8
实现int[] ints = new int[] {1,2,3,4,5}; List<Integer> list11 =Arrays.stream(ints).boxed().collect(Collectors.toList());
-
JDK16
实现int[] ints = new int[] {1,2,3,4,5}; Arrays.stream(ints).boxed().toList();
asList不可变原因分析
查看Arrays.asList
返回结果中的List
,发现其返回的是内部自己实现的ArrayList
,但该ArrayList
没有重写add
方法。
但AbstractList默认没有实现add()
方法而是抛出一个异常,从而导致无法通过调用add()
方法添加元素。