详解Java 集合类 List 的那些坑
现在的一些高级编程语言都会提供各种开箱即用的数据结构的实现,像Java编程语言的集合框架中就提供了各种实现,集合类包含Map和Collection两个大类,其中Collection下面的List列表是我们经常使用的集合类之一,很多的业务代码都离不开它,今天就来看看List列表的一些坑。
第一个坑:Arrays.asList方法返回的List不支持增加、删除操作
例如我们执行以下代码:
Liststrings=Arrays.asList("m","g"); strings.add("h");
会抛出java.lang.UnsupportedOperationException异常,此时你内心OSwhat?明明返回的ArrayList为啥不能往里面增加元素,这以后还能好好的增加元素吗?,然后果断开启Debug大法:
发现返回的ArrayList并不是我们常用的java.util.ArrayList,而是Arrays的内部类java.util.Arrays.ArrayList。进入方法Arrays.asList源码如下:
publicstaticList asList(T...a){ returnnewArrayList<>(a); }
方法返回的是Arrays的静态内部类java.util.Arrays.ArrayList,该类虽然和java.util.ArrayList也继承自抽象类java.util.AbstractList,但是通过该类的源码发现它并没有对抽象父类AbstractList的add方法默认就是抛出java.lang.UnsupportedOperationException异常。
这个坑的根本原因是我们调用返回的strings的add方法是继承自抽象父类的add方法,而抽象父类的方法默认就是抛出java.lang.UnsupportedOperationException这个异常。
第二个坑,Arrays.asList方法返回的新List和该方法原始入参数组修改会相互影响
Arrays.asList方法除了上面这个不支持增加、删除元素这个坑之外,还有另外一个坑:
从以上代码可以发现,对原始数组的修改会影响我们通过Arrays.asList方法获得的新List,深入java.util.Arrays.ArrayList的源码:
privatestaticclassArrayListextendsAbstractList implementsRandomAccess,java.io.Serializable { privatestaticfinallongserialVersionUID=-2764017481108945198L; privatefinalE[]a; ArrayList(E[]array){ a=Objects.requireNonNull(array); } ... }
可以发现是直接使用了原始的数组,所有当我们使用Arrays.asList方式获得的List时要特别注意,因为共享了数组,相互修改时可能产生一些意想不到的Bug。标准的姿势之一是将其作为ArrayList构造方法的参数重新new一个List出来即可(e.g.List
第三个坑,直接遍历List集合删除元素会报错
在直接遍历集合元素时增加、删除元素会报错,比如执行如下代码:
ListstringList=Lists.newArrayList("m","g","h"); for(Strings:stringList){ if(Arrays.asList("m","h").contains(s)){ stringList.remove(s); } }
以上代码可以正常编译通过,但是执行时会抛出java.util.ConcurrentModificationException异常,查看其源码可以发现,删除元素方法remove会使集合结构发生修改,也就是modCount(集合实际修改的次数)会修改,在循环过程中,会比较当前List的集合实际修改的次数modCount与迭代器修改的次数expectedModCount,而expectedModCount是初始化时的modCount,二者不相等,就会报ConcurrentModificationException异常。解决方法主要有两种方式,1.使用ArrayList的迭代器方式遍历,然后调用其中的方法。2.在JDK1.8+可以使用removeIf方法进行删除操作。
最后扎心一问:调用ArrayList的remove方法传入int基本类型的数字和Integer包装类型的数字,执行结果是不是一样的?
到此这篇关于详解Java集合类List的那些坑的文章就介绍到这了,更多相关JavaList集合类坑内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。