ArrayList removeRange方法分析

先给出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     }
复制代码

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值