A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© tong000 中级黑马   /  2017-3-15 14:28  /  979 人查看  /  1 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

subList方法生成的表只是原表的视图,实际上还是对原表的操作,所以这里假设有这么一个问题,现在一个列表有50个元素,要求是删除下标为20~30的元素,那么我们第一个想法是什么?遍历这个列表,再删掉对吧?下面看下删除的程序。


循环删除列表元素

这边有个注意的就是如果没问倒序的话,前面删完了,后面的元素会往前面移,所以会导致删掉的是20,22,24,26...十个元素。当然这边如果用subList方法,一句代码就可以搞定了,不用循环。



subList删除列表元素

上一篇文章中说subList的四个方法都是对原表的操作,所以这边可以直接就删掉了。

那么接下来我们来看下subList的一个注意点,subList生成的列表既然是对原表的操作,那么这时候我们操作原表,那么这个视图也会跟着变化吗?



测试程序

程序比较简单,这边就不详细说明的。直接来看下运行结果。



运行结果

可以看到在list2.size()中报了一个并发修改的错误,那么这个错误是怎么产生的呢?直接进源码看下。

public int size() {

checkForComodification();

return size;

}

size方法比较简单就直接写出来了,这里进来的是检验了一次是否并发修改,我们具体来看下checkForCommodification方法。



checkForCommodification方法

这里的expectedModCount:表示对ArrayList修改次数的期望值,它的初始值为modCount(在SubList的构造函数里面赋值)。

modCount是AbstractList类中的一个成员变量,所以我们在修改原表的时候,modCount加1了但是这边的expectedModCount却没有重新赋值(大家可以看下ArrayList的add方法,这里有对modCount加1,代码比较多就不贴出来了),所以修改了原表之后,modCount为1但是expectedModCount为0两个就是不想等了,所以这里就报了这个异常了。大家也可以看下SubList类下的其他方法,比如set,get,add方法等,都会检测两个值是否相等。这里我们可以在生成视图后,将原列表设为只读状态。

只要加上list=
Collections.unmodifiableList(list);这句代码就可以了。这样就把原表锁定了,有什么好处,大家可以研究研究哈。比如说,我有个List里面的元素有50个,我前面30个是重要的数据,不能修改的,那么,我是不是就可以用这个subList生成视图后把原列表锁定,就可以保护前面30个不被修改了呢(当然subList生成的列表是除掉三十个元素的列表)?


来自宇宙超级黑马专属苹果客户端来自宇宙超级黑马专属苹果客户端

1 个回复

倒序浏览
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马