博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ArrayList removeRange方法分析
阅读量:6528 次
发布时间:2019-06-24

本文共 3514 字,大约阅读时间需要 11 分钟。

    一文中提到了“为什么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
ints = new ArrayList
(Arrays.asList(0, 1, 2,3 3, 4, 5, 6));4 // fromIndex low endpoint (inclusive) of the subList5 // toIndex high endpoint (exclusive) of the subList6 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
subList(int fromIndex, int toIndex) {2 return (this instanceof RandomAccess ?3 new RandomAccessSubList
(this, fromIndex, toIndex) :4 new SubList
(this, fromIndex, toIndex));5 }

    ArrayList实现了RandomAccess接口(可以看),所以返回RandAccessSubList<E>(this,fromIndex,toIndex)。this、fromIndex、toIndex在上例中分别是ints、2、4。

    下面是RandAccessSubList<E>(this,fromIndex,toIndex)的源码。

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

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

1 SubList(AbstractList
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类来调用这个方法。

    终于真相大白了哈哈哈哈哈。是的,真相永远只有一个!

 

转载地址:http://eatbo.baihongyu.com/

你可能感兴趣的文章
用hadoop中的libhdfs和fuse-dfs构建快速云存储
查看>>
VMTools和虚拟硬件升级
查看>>
不知道自己不知道(Unknown Unknowns)的知识决定了你的发展
查看>>
Apple Watch的非“智能手表”卖点
查看>>
fedora17升级到fedora18
查看>>
单例模式(Singleton)
查看>>
函数指针和指针函数
查看>>
认识配置设置文件(INI与XML)
查看>>
DZ!NT论坛 3.6.711删除用户各种错解决方案
查看>>
Python的函数参数传递:传值?引用?
查看>>
[转]分享2011年8个最新的jQuery Mobile在线教程
查看>>
android call require api level
查看>>
Mac下android环境搭建
查看>>
创建Visual Studio项目模版向导的几篇参考文章
查看>>
深入浅出SQL Server Replication第一篇:走近Replication(上)
查看>>
[TopCoder][SRM] SRM 562 DIV 2
查看>>
SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第一篇)
查看>>
LocalAlloc,VirtualAlloc,malloc,new的异同
查看>>
回调函数
查看>>
win7 x64 jdk1.7.0_51
查看>>