zoukankan      html  css  js  c++  java
  • 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类来调用这个方法。

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

    如果本文对您有帮助,点一下右下角的“推荐”
  • 相关阅读:
    Siege 3.0 正式版发布,压力测试工具
    Pomm 1.1.2 发布,专为 PG 设计的 ORM 框架
    Whonix 0.5.6 发布,匿名通用操作系统
    国内开源 java cms,Jspxcms 2.0 发布
    EZNamespaceExtensions.Net v2013增加对上下文菜单、缩略图、图标、属性表的支持
    GNU Guile 2.0.9 发布,Scheme 实现
    jdao 1.0.4 发布 轻量级的orm工具包
    OpenSearchServer 1.4 RC4 发布
    Percona Server for MySQL 5.5.3030.2
    Samba 4.0.5 发布
  • 原文地址:https://www.cnblogs.com/hzmark/p/ArrayList_removeRange.html
Copyright © 2011-2022 走看看