ArrayList removeRange方法分析
《ArrayList原码分析》一文中提到了“为什么removeRange(int fromIndex,int toIndex)是protected的?”
先给出removeRange(int fromIndex,int toIndex)方法的源码(这段代码是干什么的就不再解释了,源码分析一文中已经说明)

1 protected void removeRange(int fromIndex, int toIndex) {
2 modCount++;
3 int numMoved = size - toIndex;
4 System.arraycopy(elementData, toIndex, elementData, fromIndex,
5 numMoved);
6
7 // Let gc do its work
8 int newSize = size - (toIndex-fromIndex);
9 while (size != newSize)
10 elementData[--size] = null;
11 }

可以看明白removeRange方法将制定范围内的元素都“删除”了,为什么这个方法不暴露给用户使用呢?
上网查了部分资料,靠谱一点的解释如下:http://stackoverflow.com/questions/2289183/why-is-javas-abstractlists-removerange-method-protected

再结合例子去验证,看一下代码及执行结果:

1 public static void main(String[] args) {
2 ArrayList<Integer> ints = new ArrayList<Integer>(Arrays.asList(0, 1, 2,
3 3, 4, 5, 6));
4 // fromIndex low endpoint (inclusive) of the subList
5 // toIndex high endpoint (exclusive) of the subList
6 ints.subList(2, 4).clear();
7 System.out.println(ints);
8 }

运行结果为:[0, 1, 4, 5, 6]
有没有发现这个结果就像是调用了removeRange(2,4)!这是怎么回事?接着看!
由于ArrayList并没有实现subList(int fromIndex,int toIndex)方法,所以调用的是父类的方法。看到父类AbstractList的subList方法:

1 public List<E> subList(int fromIndex, int toIndex) {
2 return (this instanceof RandomAccess ?
3 new RandomAccessSubList<E>(this, fromIndex, toIndex) :
4 new SubList<E>(this, fromIndex, toIndex));
5 }

ArrayList实现了RandomAccess接口(可以看《ArrayList原码分析》),所以返回RandAccessSubList<E>(this,fromIndex,toIndex)。this、fromIndex、toIndex在上例中分别是ints、2、4。
下面是RandAccessSubList<E>(this,fromIndex,toIndex)的源码。

1 class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
2 RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
3 super(list, fromIndex, toIndex);
4 }

只是调用了父类的构造方法。下面给出被调用的构造方法。

1 SubList(AbstractList<E> list, int fromIndex, int toIndex) {
2 if (fromIndex < 0)
3 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
4 if (toIndex > list.size())
5 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
6 if (fromIndex > toIndex)
7 throw new IllegalArgumentException("fromIndex(" + fromIndex +
8 ") > toIndex(" + toIndex + ")");
9 l = list;
10 offset = fromIndex;
11 size = toIndex - fromIndex;
12 expectedModCount = l.modCount;
13 }

至此subList方法调用结束。接着看clear()方法。由于subList方法返回的是List<E>所以该clear方法将调用AbstractList类的clear()方法。

1 public void clear() {
2 removeRange(0, size());
3 }

终于看到removeRange了,看到希望了。

1 protected void removeRange(int fromIndex, int toIndex) {
2 checkForComodification();
3 l.removeRange(fromIndex+offset, toIndex+offset);
4 expectedModCount = l.modCount;
5 size -= (toIndex-fromIndex);
6 modCount++;
7 }

这是被调用的removeRange方法,看到没有,里面执行了l.removeRange(fromIndex+offset,toIndex+offset),知道l是谁吗?l定义在SubList中,还记得嗲用SubList方法传入的list吗?还记得调用subList时传入的this吗?还记得大明湖畔的夏雨荷吗?!!!跑题了~~~
至此将进入ArrayList的removeRange(int fromIndex,int toIndex)方法。绕了一个大弯终于通过调到了这个方法,可是又有一个疑问了:调用了subList了不是通过返回的List<E>调用了clear吗?仔细观察会发现其实传到SubList构造方法中并被保存的一直是原来的ArrayList,所以调用removeRange的时候毫无疑问是对原先的List进行了处理!!!
在结合那段英文的解释,为了避免冗余......所以没对用户开放,当然你可以继承ArrayList编写自己的List类来调用这个方法。
终于真相大白了哈哈哈哈哈。是的,真相永远只有一个!
ArrayList removeRange方法分析的更多相关文章
- ArrayList源码分析--jdk1.8
ArrayList概述 1. ArrayList是可以动态扩容和动态删除冗余容量的索引序列,基于数组实现的集合. 2. ArrayList支持随机访问.克隆.序列化,元素有序且可以重复. 3. ...
- ArrayList源码分析超详细
ArrayList源码分析超详解 想要分析下源码是件好事,但是如何去进行分析呢?以我的例子来说,我进行源码分析的过程如下几步: 找到类:利用 IDEA 找到所需要分析的类(ztrl+N查找ArraLi ...
- 【Java入门提高篇】Day21 Java容器类详解(四)ArrayList源码分析
今天要介绍的是List接口中最常用的实现类——ArrayList,本篇的源码分析基于JDK8,如果有不一致的地方,可先切换到JDK8后再进行操作. 本篇的内容主要包括这几块: 1.源码结构介绍 2.源 ...
- Java - ArrayList源码分析
java提高篇(二一)-----ArrayList 一.ArrayList概述 ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 nul ...
- java集合框架03——ArrayList和源码分析
最近忙着替公司招人好久没写了,荒废了不好意思. 上一章学习了Collection的架构,并阅读了部分源码,这一章开始,我们将对Collection的具体实现进行详细学习.首先学习List.而Array ...
- ArrayList源码分析超详细(转载)
ArrayList源码分析超详细 ArrayList源码分析超详解 想要分析下源码是件好事,但是如何去进行分析呢?以我的例子来说,我进行源码分析的过程如下几步: 找到类:利用 IDEA 找到所需要 ...
- ArrayList源码分析(JDK1.8)
概述 ArrayList底层是基于数组实现的,并且支持动态扩容的动态数组(变长的集合类).ArrayList允许空值和重复的元素,当向ArrayList中添加元素数量大于其底层数组容量时,会通过扩容机 ...
- Java ArrayList源码分析(含扩容机制等重点问题分析)
写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...
- 编写测试类,了解ArrayList的方法
这篇文章主要介绍了C#中动态数组用法,实例分析了C#中ArrayList实现动态数组的技巧,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了C#中动态数组用法.分享给大家供大家参考.具体分析如下 ...
- java ArrayList的序列化分析
一.绪论 所谓的JAVA序列化与反序列化,序列化就是将JAVA 对象以一种的形式保持,比如存放到硬盘,或是用于传输.反序列化是序列化的一个逆过程. JAVA规定被序列化的对象必须实现java.io.S ...
随机推荐
- C语言中的数据类型及其转换
目录 计算机中的数据类型 整型数据之间的转换 相同字长之间的转换 小字长转大字长 大字长转小字长 int.float.double之间的转换 float->double double->f ...
- canvas实现图片标记
前言 由于业务需求,需要有一个图片标记功能,其实就是对图片画框画线做标记,类似微信的图片编辑 但是需要存下标记图及其标记的具体数据,.功能其实很简单,但刚开始的时候也是费了一些功夫的.我将原项目中该功 ...
- MoCov1: 无监督视觉表征学习的动量对比《Momentum Contrast for Unsupervised Visual Representation Learning》(MoCo、动量对比、动态字典、队列维护、对比损失InfoNCE)
现在是2024年6月11日,21:49,刚找好要看的论文,师兄推荐的. 先占个坑,明天看,我累了(我没脑子了). 现在是6月12日,15:49,干正事了(又被别人影响了情绪,这不好,希望你改掉,好的, ...
- CSS – Font Family
前言 font-family 虽然只是一个 CSS 属性, 但是牵连许多东西, 所以独立一篇来讲. 网站一般上会使用 Google Fonts 作为 font-family, 下面会以一个 Googl ...
- CSS – 实战 Spacing & Layout
前言 这篇想整理一下在网页开发中, Spacing (间距) 和 Layout 排版是如果被处理的. Spacing 介绍 东西密密麻麻会给人一种很恐怖的感觉. 只要加上一点空间 (间距), 整体感觉 ...
- HTML & CSS – Styling List
前言 ul > li 经常会用到, 它原本的 style 很丑, 这篇介绍如果修改它. 以前学 W3Schools 的时候也有记入过: HTML – W3Schools 学习笔记 参考: You ...
- MyBatis——案例——查询-查询详情
查询-查询详情 (根据id获取商品全部信息(即商品对象)) 1.编写Mapper接口方法:Brand selectById(int id); 2.编写SQL ...
- 如何用VMWARE创建一个Linux虚拟机
序言 各位好啊,我是会编程的蜗牛,作为java开发者,我们都是需要接触Linux服务器的,一般部署应用都是部署在Linux服务器上的~ 但一般的服务器要么需要购买,要么只是公司里的,那么有没有免费的L ...
- LeetCode 1397. Find All Good Strings 找到所有好字符串 (数位DP+KMP)
好题- 就是比平时的 hard 难了一些-- 虽然猜出是数位DP了-不过比我之前做的题,好像多了一维,印象中都是一维记录之前状态就够了--然后就没做出-- 至于 KMP 的应用更是神奇,虽然掌握的 k ...
- 使用 vuex 和 本地存储实现永久性token存在 并且在请求拦截统一添加headers token 避免重复代码
在 vuex 仓库中设置state的token值:从本地中取值: 登录的时候调用唯一可以修改state数据的mutations方法设置token : export default new Vuex.S ...