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 ...
随机推荐
- 呵,老板不过如此,SQL还是得看我
2018年7月,大三暑假进行时,时间过得飞快,我到这边实习都已经一个月了. 我在没工作之前,我老是觉得生产项目的代码跟我平时自学练的会有很大的区别. 以为生产项目代码啥的都会规范很多,比如在接口上会做 ...
- 【YashanDB知识库】生成迁移报告失败,"报错未知类型错误异常:"
[标题]YMP迁移 [问题分类]迁移报告 [关键字]迁移报告.未知类型错误异常 [问题描述]下载迁移报告时报错"未知类型错误异常:",一长串英文 日志报错: [问题原因分析]jav ...
- linux修改limits.conf不生效
正常情况下, /etc/security/limits.conf 的改动,重新登录就可以生效, 我遇到的问题最后的解决方案是重启虚拟机解决了,也参考了很多网上的文章,整理记录一下 一.修改方法 1.临 ...
- c++ push_back()和emplace_back()区别
c++ push_back()和emplace_back()区别 References C++中push_back和emplace_back的区别 push_back v.s. emplace_bac ...
- numpy argsort排序如何让其稳定排序
numpy.argsort(a, axis=-1, kind=None, order=None) Parameters: aarray_like Array to sort. axis int or ...
- Nuxt Kit 中的页面和路由管理
title: Nuxt Kit 中的页面和路由管理 date: 2024/9/17 updated: 2024/9/17 author: cmdragon excerpt: 摘要:本文介绍了Nuxt ...
- 补天云全网独有技术和唯一实用工具:QT6框架QML源码保护工具应用 QML和JavaScript源码隐藏工具
如何保护和隐藏你的QT应用中的QML源代码?补天云全网独有技术和唯一实用工具:QT6框架QML源码保护工具应用 QML和JavaScript源码隐藏工具 简介 在通常的QT QML应用程序中,QML语 ...
- iframe嵌套登录页-页面无法加载
背景 活动页面和登录页跨域,过去都是跳转到登录页登录之后再跳转回来,体验不好. 现在需要将登录模块嵌入到活动页,因为懒,不想开发重复的模块,首先我想到的是iframe 刚开始还能正常使用,一段时间后安 ...
- async/await和Grand Central Dispatch代码切换
很多iOS开发开始学习结构化并发时已经用过了很多年Grand Central Dispatch,虽然从思想上二者区别很大,但是利用熟悉的东西去理解新的事物有助于提升学习理解的效率,接下来是这Grand ...
- Kubernetes的Pod调度:让你的应用像乘坐头等舱!
一.Kubernetes 中 Pod 调度的重要性 在 Kubernetes 的世界里,Pod 调度就像是一个繁忙的交通指挥官,负责把小车(也就是我们的 Pod)送到最合适的停车位(节点).调度不仅关 ...