码迷,mamicode.com
首页 > 编程语言 > 详细

JAVA Collection 源码分析(二)之SubList

时间:2014-08-01 15:24:21      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   java   io   数据   for   cti   

  昨天我们分析了ArrayList的源码,我们可以看到,在其中还有一个类,名为SubList,其继承了AbstractList。

// AbstractList类型的引用,所有继承了AbstractList都可以传进来
 private final AbstractList<E> parent;
//       这个是其实就是parent的偏移量,从parent中的第几个元素开始的
        private final int parentOffset;
        private final int offset;
        int size;

        SubList(AbstractList<E> parent,
                int offset, int fromIndex, int toIndex) {
            this.parent = parent;
            this.parentOffset = fromIndex;
            this.offset = offset + fromIndex;
            this.size = toIndex - fromIndex;
            this.modCount = ArrayList.this.modCount;
        }
// 从上面我们可以看出,其实就是一个相对的过程,截取完了以后还是原来的List,只是这里面
// 用了一个很巧妙的方法,用了offset的这个偏移量,他就指向我们截取过后的list的首个元素,
// 从下面的方法我们也可以看出,真是巧妙的数据结构的设计
// 以下就是它实现的具体方法,主要是注意到,现在的index都是相对于offset以后的位置
public E set(int index, E e) {
            rangeCheck(index);
            checkForComodification();
            E oldValue = ArrayList.this.elementData(offset + index);
            ArrayList.this.elementData[offset + index] = e;
            return oldValue;
        }

        public E get(int index) {
            rangeCheck(index);
            checkForComodification();
            return ArrayList.this.elementData(offset + index);
        }

        public int size() {
            checkForComodification();
            return this.size;
        }

        public void add(int index, E e) {
            rangeCheckForAdd(index);
            checkForComodification();
            parent.add(parentOffset + index, e);
            this.modCount = parent.modCount;
            this.size++;
        }

        public E remove(int index) {
            rangeCheck(index);
            checkForComodification();
            E result = parent.remove(parentOffset + index);
            this.modCount = parent.modCount;
            this.size--;
            return result;
        }

        protected void removeRange(int fromIndex, int toIndex) {
            checkForComodification();
            parent.removeRange(parentOffset + fromIndex,
                               parentOffset + toIndex);
            this.modCount = parent.modCount;
            this.size -= toIndex - fromIndex;
        }

        public boolean addAll(Collection<? extends E> c) {
            return addAll(this.size, c);
        }

        public boolean addAll(int index, Collection<? extends E> c) {
            rangeCheckForAdd(index);
            int cSize = c.size();
            if (cSize==0)
                return false;

            checkForComodification();
            parent.addAll(parentOffset + index, c);
            this.modCount = parent.modCount;
            this.size += cSize;
            return true;
        }

  在subLIst我们可以找到我们昨天分析的modCount的答案,为什么对数组每次操作都要进行modCount++的操作,我们可以找到checkForComodification()这个方法,其实就是在迭代中,校验expectedModCount 等不等于 ArrayList.this.modCount

因为每次对数组进行操作的时候,modCount都会进行++,所以如果不相等的,就会报错,并发所产生的错误。

  所以Sublist其实就是还是原来的List,只是它在内部进行了巧妙的封装变换,这就是它的最大魅力所在。

JAVA Collection 源码分析(二)之SubList,布布扣,bubuko.com

JAVA Collection 源码分析(二)之SubList

标签:style   blog   color   java   io   数据   for   cti   

原文地址:http://www.cnblogs.com/xz0636/p/3884849.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!