目录
很多人会使用Arrays.asList来将数组转成List,但是里面的坑有多少你知道吗?
坑
此List非彼List
你以为转出来的List就可以用add,remove等等方法吗,太天真了
它是转成内部自己定义的list,所以调用remove,add会报错UnsupportedOperationException错误
Arrays.asList参数不能为基础类型
为啥?
public static void main(String[] args) {
int a[]={1,2};
List list=Arrays.asList(a);
System.out.println(list.get(1));
}
会报错ArrayIndexOutOfBoundsException
它实际里面只有一个值,list.get(0),而这个值是数组的地址
为啥会这么奇怪?原因在下面:
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
会涉及到下面的讲解
T...
其实这个T...和T[]没什么两样,但是T...会有点坑,就是传入基础类型它会储存为数组的地址进去。
T[]就不允许传入基础类型,它叫做支持对象类型 ,基础类型不算对象了。
举个栗子:
package com.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class test3 {
public static void main(String[] args) {
/*int a[]={1,2};
List list=Arrays.asList(a);
System.out.println(list.get(1));
Integer b[]={1,2};
List list1=Arrays.asList(b);*/
int a[]={1,2};
new b().asList(a);
Integer c[]={1,2};
new b().asList(c);
}
static class b{
public <T> List<T> asList(T... a) {
System.out.println(a);
return b(a);
}
<T> List<T> b(T[] array){
System.out.println(array);
return new ArrayList<>();
}
}
}
这样是可以运行的,输出
[[I@5b80350b
[[I@5b80350b
[Ljava.lang.Integer;@5d6f64b1
[Ljava.lang.Integer;@5d6f64b1
可以看到存入一个是地址,一个是数组,而且T...和T[]没有区别
如果把asList重写为
public <T> List<T> asList(T[] a) {
System.out.println(a);
return b(a);
}
立马报错,所以说T...有个坑就是传入基础类型不会报错,就是换成数组地址了。
重点
在其他使用泛型的类参数不要传入基础类型,而是他们的封装类。
你试下有没有List<int>类型,hhh,只有List<Integer>类型
正确使用
Integer a[]={1,2};
List list=Arrays.asList(a).stream().collect(Collectors.toList());
System.out.println(list.get(1));
使用lambda表达式转换
注意点
如果是基础类型也会出现错误,
那怎么办?
int a[]={1,2};
List list=Arrays.stream(a).boxed().collect(Collectors.toList());
System.out.println(list.get(1));
参考这篇文章,还有自己的思考总结