java学习|图说集合(二)熟悉又陌生的ArrayList

相信说起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

微信群请点击公众号菜单进微信群

我们哦~

文字: 微笑的小小刀

排版:花音

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值