码农的世界里,每天的工作是堆码,生活亦是堆码,这应该是资深攻城狮的境界吧!堆码的过程中我们经常会遇到数组转换为集合的应用场景,而最常用的转换操作应该就是java.util.Arrays.asList()了吧。今天转换的过程中偶然遇见了一个转换错误,记录下来供日后不小心踩坑的童鞋们参考!!!
一、事情起因
整数数组要转换成List集合并且删除第一个元素,于是就用了下面这段代码:
感觉结果应该是顺理成章的把11移除掉了,然并卵:
二、寻因究果
执行情况非但没有达到预期的结果,竟然还报了异常,why? 带着疑问看了下源码,转换成了ArrayList对象,好像并没有什么不妥。。。
问题出在了哪里呢?就在这时候突然看到了一个重点:
看到这个地方就明白了吧,只想说“擦,还有这种操作!” ,转换来的ArrayList竟然不是java.util.ArrayList,而是java.util.Arrays的一个内部类名称叫ArrayList。这个内部类ArrayList并没有实现java.util.List接口,只是继承了抽象类java.util.AbstractList,没有重写add()和remove()方法,所以转换后的List集合调用remove()方法其实是运行的AbstractList.remove()的方法。
于是就出现了文章开头的那个触目惊心的异常,此时我们已经明白了事情的原委,有因才有果!
三、扩散探索
本着打破砂锅问到底的精神,又去搜集了下转换时可能出现的其他异常场景,记录在此,供大家参考。
-
不能把基础数据类型转化为列表
打印出来的转换结果是一个对象,asList方法入参是个泛型的变长参数,而基本类型是无法泛化的。
转换基础类型数组可以用下面的方法:
-
不支持集合add()和remove()方法
这一点文章开头的例子可以证明,asList()方法是返回一个定长不可变的java.util.Arrays.ArrayList(),没有实现List接口。
-
生成的ArrayList和原始数组任意一个数值变化,会级联影响
如上图所示,我们先打印出改变元素前的数组和List,再改变转换List中的一个元素打印数组和List的结果,改变数组中元素,再打印数组和List的结果:可以看到,改变转换为List的元素,原有数组的值也会跟着改变。
附:本文所有测试示例均是在JDK1.8版本下,不同版本源码或稍有不同!
PS:本次总结的就先到此为止啦,冰冰棒才疏学浅,不当之处欢迎大家指正!