美文网首页
JDK源码阅读 0826 - 抽象集合

JDK源码阅读 0826 - 抽象集合

作者: 学习吧朱小宁 | 来源:发表于2020-08-31 10:25 被阅读0次

    我们经常在代码中使用到List 、Set 、 Map ,也粗略看过一些实现类的源码解析。现在去看下抽象类集合中的方法与具体实现类有哪些不同。

    public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> 
    public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> 
    public abstract class AbstractMap<K,V> implements Map<K,V>
    

    由上述代码可以看到 AbstractSet与 AbstractList 都继承了 AbstractCollection 然后去实现自己的方法 AbstractMap 单独实现Map的方法


    AbstractList .png
    AbstractSet.png

    AbstractSet 只有较少的方法 除空构造函数之外 ,重写了Object 类 equal() 与 hashCode()


    AbstractSetFunction.png

    AbstractList 重写了较多的方法,其中大部分都是经常使用到的 包含 add(E) get(int) set(int,E) remove(int) indexOf(Object) clear() addAll(int Collection) 等等 其中add() remove() 等方法种其实并无具体实现,标注其实现类应抛出 UnsupportedOperationException()

     /**
         * {@inheritDoc}
         *
         * <p>This implementation always throws an
         * {@code UnsupportedOperationException}.
         *
         * @throws UnsupportedOperationException {@inheritDoc}
         * @throws ClassCastException            {@inheritDoc}
         * @throws NullPointerException          {@inheritDoc}
         * @throws IllegalArgumentException      {@inheritDoc}
         * @throws IndexOutOfBoundsException     {@inheritDoc}
         */
        public void add(int index, E element) {
            throw new UnsupportedOperationException();
        }
    
    AbstractListFunction.png

    在去看ArrayList 源码时候,追溯扩展列表长度时偶然发现一个好玩的事情。 ensureCapacityInternal(int ) 逐步追溯发现ensureExplicitCapacity()中第一行为 操作modCount ,这个属性ArrayList 并不存在,存在于AbstractList中,且对其的注释准确解释了以前不理解的某些异常。

     private void ensureCapacityInternal(int minCapacity) {
            ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
        }
     private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
    
        /**
         * The number of times this list has been <i>structurally modified</i>.
         * Structural modifications are those that change the size of the
         * list, or otherwise perturb it in such a fashion that iterations in
         * progress may yield incorrect results.
         *
         * <p>This field is used by the iterator and list iterator implementation
         * returned by the {@code iterator} and {@code listIterator} methods.
         * If the value of this field changes unexpectedly, the iterator (or list
         * iterator) will throw a {@code ConcurrentModificationException} in
         * response to the {@code next}, {@code remove}, {@code previous},
         * {@code set} or {@code add} operations.  This provides
         * <i>fail-fast</i> behavior, rather than non-deterministic behavior in
         * the face of concurrent modification during iteration.
         *
         * <p><b>Use of this field by subclasses is optional.</b> If a subclass
         * wishes to provide fail-fast iterators (and list iterators), then it
         * merely has to increment this field in its {@code add(int, E)} and
         * {@code remove(int)} methods (and any other methods that it overrides
         * that result in structural modifications to the list).  A single call to
         * {@code add(int, E)} or {@code remove(int)} must add no more than
         * one to this field, or the iterators (and list iterators) will throw
         * bogus {@code ConcurrentModificationExceptions}.  If an implementation
         * does not wish to provide fail-fast iterators, this field may be
         * ignored.
         */
        protected transient int modCount = 0;
    

    简单的理解modCount这个属性就是 记录当前List 操作过的次数,如果更改列表大小或者其他方式更新列表进度 就会导致异常。如果需要提供快速失败的方法,就在add() 和 remove() 方法 中对列表进行结构修改,会抛出ConcurrentModificationExceptions 。
    模拟一次, 在列表迭代中,如果对列表进行删除会首先触发ensureExplicitCapacity()modCount ++ ,在进行下次迭代时候触发checkForComodification() 比对expectedModCount 不同则抛出异常

     final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
     /**
             * The modCount value that the iterator believes that the backing
             * List should have.  If this expectation is violated, the iterator
             * has detected concurrent modification.
             */
            int expectedModCount = modCount;
    
    

    在此之上,AbstractList中存在了几个内部类,用于迭代展示获取等情况,具体没有搞明白下次具体分析下。

    AbstractMapFunction.png

    AbstractMap 中实现的方法与AbstractList 基本相同,其中不同的只是关于Map 的键值映射关系,例如 KeySet() values() 等
    在其中, remove方法中存在 Iterator 迭代其进行寻找并进行删除的方法, 这个迭代器 在AbstractList中也被用到,不过封装于内部实现类中 ListIterator 封装了三层。。。

        public V remove(Object key) {
            Iterator<Entry<K,V>> i = entrySet().iterator();
            Entry<K,V> correctEntry = null;
            if (key==null) {
                while (correctEntry==null && i.hasNext()) {
                    Entry<K,V> e = i.next();
                    if (e.getKey()==null)
                        correctEntry = e;
                }
            } else {
                while (correctEntry==null && i.hasNext()) {
                    Entry<K,V> e = i.next();
                    if (key.equals(e.getKey()))
                        correctEntry = e;
                }
            }
    
            V oldValue = null;
            if (correctEntry !=null) {
                oldValue = correctEntry.getValue();
                i.remove();
            }
            return oldValue;
        }
    
    
      /**
         * {@inheritDoc}
         *
         * <p>This implementation returns a straightforward implementation of the
         * {@code ListIterator} interface that extends the implementation of the
         * {@code Iterator} interface returned by the {@code iterator()} method.
         * The {@code ListIterator} implementation relies on the backing list's
         * {@code get(int)}, {@code set(int, E)}, {@code add(int, E)}
         * and {@code remove(int)} methods.
         *
      */
      public ListIterator<E> listIterator(final int index) {
            rangeCheckForAdd(index);
    
            return new ListItr(index);
        }
    
        private class Itr implements Iterator<E> {  
    //do something
    XXX
    }
    private class ListItr extends Itr implements ListIterator<E>{
    XXX
    }
    
    

    相关文章

      网友评论

          本文标题:JDK源码阅读 0826 - 抽象集合

          本文链接:https://www.haomeiwen.com/subject/gcqxsktx.html