相信说起ArrayList,
大家都会会心一笑,
这货从我们接触java编程时就一直陪伴着我们,
只要是存多个数据的,
基本上都会写上一句:
List list = new ArrayList().
然后开始增删改查遍历等各种操作。
我们熟悉的ArrayList
List<T> list = new ArrayList();
list.add(T);
list.get(0);
list.remove(0);
for(T t : list){
//todo:
}
众所周知,list有两种常用实现, 一种是ArrayList, 一种是LinkedList, 但据我在工作中的观察,好像新建list的时候都习惯直接新建成了arrayList;从mybatis返回数据库数据时也默用的arrayList 。 但这并不是说LinkedList就不重要了。如下图所示,两者的结构差别很大。
记得刚出来找工作面试时,我给面试官看我以前写的代码:
ArrayList<T> listA = new ArrayList<>();
ArrayList<T> listB. = new ArrayList<>();
在初始化的时候,我都是直接用ArrayList声明的,而不是现在常用的List声明,实现类再具体指定。当时面试官问我,你觉得这样写有没有什么问题, 我当时答的是: 代码运行没什么问题,别的问题还不知道。现在看来,问题真的是太多了。
可能会陌生的ArrayList
陌生的新建list
先从上面继续说, 用ArrayList<T> listA = new ArrayList<>()去新建一个list会有什么问题
问题在于不能变更成其他类型的list,见如下代码:
当我想把LinkedList赋值给listA时,会报如上错误,但如果用List<String> listA = new ArrayList<>()时就不会出现上述问题,如下图所示:
陌生的删除操作
有这么一个需求,我们需要在list中删除某个元素。那拿到这个需求后的第一想法就是遍历一遍,找到那个元素然后删掉:
代码看起来没有任何问题,但一运行就报错,在上篇文章中我们有聊到过,for(T t:list )的循环实际上是基于Iterator的循环,我们从错误信息中可以看到, 是ArrayList中的Itr的next方法中的checkForComodification方法抛出了这个错误。这个Itr如下图所示,就是一个Iterator。
那么正确的删除姿势是怎样的呢?
简单提一句,
调用list的iterator ,
通过iterator的remove方法来删除:
List<String> list = new ArrayList<>();
list.add("aaa");list.add("bbb");list.add("ccc");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if(next.equals("aaa")){
iterator.remove();
}
}
然后给大家发糖糖,上面那么一大堆的代码才完成了一个删除的功能,看着都烦,可以尝试下以下写法,功能是一模一样的:
List<String> list = new ArrayList<>();
list.add("aaa");list.add("bbb");list.add("ccc");
list.removeIf(next -> next.equals("aaa"));
System.out.println(list);
陌生的截取操作
开局放张图
结果我相信小伙伴们都能正确答出来,甚至于以后拿这个subList做增删改查都没问题,但请注意划红线部分, 这时候我们已是不是在操作ArrayList了, 而是在操作ArrayList中的SubList类:
可以看到,
他拥有的方法
和我们外面的大ArrayList差不多,
所以我们才能无感的使用下去。
但是我们可以深入看到方法细节,如SubList.remove方法:
可以看到,在修改之前先检测了,父ArrayList的modCount , 和自己的(SubList)的expectedModCount是否相等。如果不相等则抛出ConcurrentModificationException;那我们就先操作父ArrayList , 再操作SubList试一下:
嗯,果然报错了!
总结:ArrayList是我们最常用的一个工具类,但简单的操作之间也隐藏着很多操作的风险,就需要我们在调用方法的时候,小手一动,点进源码里面看一看,对哪些值做了操作,会不会有什么风险。
—END—
前期回顾:
Java学习|图说String(一):String的存储方式
java学习|图说String(二):基于byte数组的String方法调用
java学习|图说String(三)String中'+'和StringBuilder的区别
全栈工坊
QQ群:661749608
微信群请点击公众号菜单进微信群
我们哦~
文字: 微笑的小小刀
排版:花音