Arrays.asList和Lists.newList使用时的陷阱

(1)在使用Arrays.asList转成的List时同样要注意,Arrays.asList返回类型为Arrays类内部定义的私有类ArrayList,并且继承与AbstractList,翻阅AbstractList源码是可以发现,是不支持add和remove操作的,也就是说Arrays.asList返回的List是个固定大小的List。

(2)在使用com.google.common.collect提供的jar包Lists类的Lists.newArrayList方法时,有相同的问题,如果传入基本类型数组,也无法转化成一个正常的List,这一点跟ArrayList结果是一致的。但是对象数组进行转化时,有一点不同,转成的List是支持add和remove操作的。

昨天在开发中遇到一个场景,调用RPC,拿到返回结果(int[]数组),使用jackSon序列化为Json对象时,发现一个诡异的现象,在使用Lists.newArrayList和Arrays.asList将数组转为List时,转出来的对象并不是与原数组对应的一个List,二十一个很诡异的对象。后来研究一下JDK,发现了陷阱所在。

首先看一下Arrays.asList这个方法,这个方法可以将数组转成list,是JDK中java.util包中Arrays类的静态方法。

复制代码
public class ArraysTest {
 
private static void asListTest(){
 
String stringArray[]={"aa","bb","cc"};
 
List<String> sList= Arrays.asList(stringArray);
 
for(String str:sList){//能遍历出各个元素
 
System.out.println(str);
 
}
 
System.out.println(sList.size());
 
 
 
System.out.println("- - - - - - - - - - -");
 
 
 
int intArray[]={11,22,33};
 
List intList=Arrays.asList(intArray);
 
for(Object o:intList){//就一个元素
 
System.out.println(o.toString());
 
}
 
 
 
System.out.println("- - - - - - - - - - -");
 
 
 
Integer integerArray[]={11,22,33};
 
List<Integer> objList=Arrays.asList(integerArray); //数组里的每一个元素都是作为list中的一个元素
 
for(int a:objList){
 
System.out.println(a);
 
}
 
 
 
System.out.println("- - - - - - - - - - -");
 
}
 
 
 
public static void main(String[] args){
 
asListTest();
 
}
 
}
复制代码

 

结果如下:

复制代码
Connected to the target VM, address: '127.0.0.1:12064', transport: 'socket'
 
aa
 
bb
 
cc
 
3
 
- - - - - - - - - - -
 
[I@2db0f6b2
 
- - - - - - - - - - -
 
11
 
22
 
33
 
- - - - - - - - - - -
 
Disconnected from the target VM, address: '127.0.0.1:12064', transport: 'socket'
 
 
 
Process finished with exit code 0
复制代码

 

当基本类型数组使用Arrays.asList方法转List时,并不能转成正常的List,随后我看了一下jdk源码,看到问题所在

复制代码
public static <T> List<T> asList(T... a) {
 
return new ArrayList<>(a);
 
}
 
 
 
private static class ArrayList<E> extends AbstractList<E>
 
implements RandomAccess, java.io.Serializable
 
{
 
private static final long serialVersionUID = -2764017481108945198L;
 
private final E[] a;
 
 
 
ArrayList(E[] array) {
 
a = Objects.requireNonNull(array);
 
}
 
}
复制代码

 

基本类型int不是对象类型,在使用Arrays.asList时,做泛型擦除时,将int[]当做对象类型,所以转成一个只有一个元素的List。在使用Arrays.asList转成的List时同样要注意,Arrays.asList返回类型为Arrays类内部定义的私有类ArrayList,并且继承与AbstractList,翻阅AbstractList源码是可以发现,是不支持add和remove操作的,也就是说Arrays.asList返回的List是个固定大小的List。

如果希望转过后的list可以支持add和remove操作,可使用如下方法:

复制代码
/*方法一*/
 
ArrayList<Integer> copyArrays=new ArrayList<>(Arrays.asList(integerArray));
 
 
 
/*方法二*/
 
List<Integer> integerList = new ArrayList<>();
 
Collections.addAll(integerList, integerArray);
复制代码

 

如果想把一个基本类型数组转化为List,可使用如下方法:

Arrays.asList(ArrayUtils.toObject(intArray));

在使用com.google.common.collect提供的jar包Lists类的Lists.newArrayList方法时,有相同的问题,如果传入基本类型数组,也无法转化成一个正常的List,这一点跟ArrayList结果是一致的。但是对象数组进行转化时,有一点不同,转成的List是支持add和remove操作的。

 

参考:Arrays.asList和Lists.newList使用时的陷阱

posted @   aspirant  阅读(2347)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2019-10-30 兴哥:美团下一个十年,要让新一批管理者成长起来
点击右上角即可分享
微信分享提示