java集合框架02——Collection架构与源码分析

Collection是一个接口,它主要的两个分支是List和Set。如下图所示:

        List和Set都是接口,它们继承与Collection。List是有序的队列,可以用重复的元素;而Set是数学概念中的集合,不能有重复的元素。List和Set都有它们各自的实现类。

为了方便,我们抽象出AbstractCollection类来让其他类继承,该类实现类Collection中的绝大部分方法。AbstractList和AbstractSet都继承与AbstractCollection,具体的List实现类继承与AbstractList,而Set的实现类则继承与AbstractSet。

        另外,Collection中有个iterator()方法,它的作用是返回一个Iterator接口。通常,我们通过Iterator迭代器来遍历集合。ListIterator是List接口所特有的,在List接口中,通过ListIterator()返回一个ListIterator对象。

        我们首先来阅读下这些 接口和抽象类以及他们的实现类中都有哪些方法:

1. Collection

        Collection的定义如下:

public interface Collection extends Iterable {}

        从它的定义中可以看出,Collection是一个接口。它是一个高度抽象出来的集合,包含了集合的基本操作:添加、删除、清空、遍历、是否为空、获取大小等。

        Collection接口的所有子类(直接子类和简介子类)都必须实现2种构造函数:不带参数的构造函数和参数为Collection的构造函数。带参数的构造函数可以用来转换Collection的类型。下面是Collection接口中定义的API:

// Collection的API
abstract boolean         add(E object)
abstract boolean         addAll(Collection collection)
abstract void            clear()
abstract boolean         contains(Object object)
abstract boolean         containsAll(Collection collection)
abstract boolean         equals(Object object)
abstract int             hashCode()
abstract boolean         isEmpty()
abstract Iterator     iterator()
abstract boolean         remove(Object object)
abstract boolean         removeAll(Collection collection)
abstract boolean         retainAll(Collection collection)
abstract int             size()
abstract  T[]         toArray(T[] array)
abstract Object[]        toArray()

2. List

        List的定义如下:

public interface List extends Collection {}

        从List定义中可以看出,它继承与Collection接口,即List是集合的一种。List是有序的队列,List中的每一个元素都有一个索引,第一个元素的索引值为0,往后的元素的索引值依次+1.,List中允许有重复的元素。

        List继承Collection自然包含了Collection的所有接口,由于List是有序队列,所以它也有自己额外的API接口。API如下:

// Collection的API
abstract boolean         add(E object)
abstract boolean         addAll(Collection collection)
abstract void            clear()
abstract boolean         contains(Object object)
abstract boolean         containsAll(Collection collection)
abstract boolean         equals(Object object)
abstract int             hashCode()
abstract boolean         isEmpty()
abstract Iterator     iterator()
abstract boolean         remove(Object object)
abstract boolean         removeAll(Collection collection)
abstract boolean         retainAll(Collection collection)
abstract int             size()
abstract  T[]         toArray(T[] array)
abstract Object[]        toArray()
// 相比与Collection,List新增的API:
abstract void                add(int location, E object) //在指定位置添加元素
abstract boolean             addAll(int location, Collection collection) //在指定位置添加其他集合中的元素
abstract E                   get(int location) //获取指定位置的元素
abstract int                 indexOf(Object object) //获得指定元素的索引
abstract int                 lastIndexOf(Object object) //从右边的索引
abstract ListIterator     listIterator(int location) //获得iterator
abstract ListIterator     listIterator()
abstract E                   remove(int location) //删除指定位置的元素
abstract E                   set(int location, E object) //修改指定位置的元素
abstract List             subList(int start, int end) //获取子list

3. Set

        Set的定义如下:

 

public interface Set extends Collection {}

        Set也继承与Collection接口,且里面不能有重复元素。关于API,Set与Collection的API完全一样,不在赘述。

 

 

 

4. AbstractCollection

public abstract class AbstractCollection implements Collection {}

        AbstractCollection是一个抽象类,它实现了Collection中除了iterator()和size()之外的所有方法。AbstractCollection的主要作用是方便其他类实现Collection.,比如ArrayList、LinkedList等。它们想要实现Collection接口,通过集成AbstractCollection就已经实现大部分方法了,再实现一下iterator()和size()即可。

        下面看一下AbstractCollection实现的部分方法的源码:

public abstract class AbstractCollection implements Collection {
    protected AbstractCollection() {
    }

    public abstract Iterator iterator();//iterator()方法没有实现

    public abstract int size(); //size()方法也没有实现

    public boolean isEmpty() { //检测集合是否为空
        return size() == 0;
    }
    /*检查集合中是否包含特定对象*/
    public boolean contains(Object o) { 
        Iterator it = iterator();
        if (o==null) {
            while (it.hasNext()) //从这里可以看出,任何非空集合都包含null
                if (it.next()==null)
                    return true;
        } else {
            while (it.hasNext())
                if (o.equals(it.next()))
                    return true;
        }
        return false;
    }
    /*将集合转变成数组*/
    public Object[] toArray() {
        // Estimate size of array; be prepared to see more or fewer elements
        Object[] r = new Object[size()]; //创建与集合大小相同的数组
        Iterator it = iterator();
        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) // fewer elements than expected
                //Arrays.copy(**,**)的第二个参数是待copy的长度,如果这个长度大于r,则保留r的长度
                return Arrays.copyOf(r, i);
            r[i] = it.next();
        }
        return it.hasNext() ? finishToArray(r, it) : r;
    }

    public  T[] toArray(T[] a) {
        // Estimate size of array; be prepared to see more or fewer elements
        int size = size();
        T[] r = a.length >= size ? a :
                  (T[])java.lang.reflect.Array
                  .newInstance(a.getClass().getComponentType(), size);
        Iterator it = iterator();

        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) { // fewer elements than expected
                if (a == r) {
                    r[i] = null; // null-terminate
                } else if (a.length < i) {
                    return Arrays.copyOf(r, i);
                } else {
                    System.arraycopy(r, 0, a, 0, i);
                    if (a.length > i) {
                        a[i] = null;
                    }
                }
                return a;
            }
            r[i] = (T)it.next();
        }
        // more elements than expected
        return it.hasNext() ? finishToArray(r, it) : r;
    }

    private static  T[] finishToArray(T[] r, Iterator it) {
        int i = r.length;
        while (it.hasNext()) {
            int cap = r.length;
            if (i == cap) {
                int newCap = cap + (cap >> 1) + 1;
                // overflow-conscious code
                if (newCap - MAX_ARRAY_SIZE > 0)
                    newCap = hugeCapacity(cap + 1);
                r = Arrays.copyOf(r, newCap);
            }
            r[i++] = (T)it.next();
        }
        // trim if overallocated
        return (i == r.length) ? r : Arrays.copyOf(r, i);
    }
    
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError
                ("Required array size too large");
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

    // 删除对象o
    public boolean remove(Object o) {
        Iterator it = iterator();
        if (o==null) {
            while (it.hasNext()) {
                if (it.next()==null) {
                    it.remove();
                    return true;
                }
            }
        } else {
            while (it.hasNext()) {
                if (o.equals(it.next())) {
                    it.remove();
                    return true;
                }
            }
        }
        return false;
    }
   
    // 判断是否包含集合c中所有元素
    public boolean containsAll(Collection c) {
        for (Object e : c)
            if (!contains(e))
                return false;
        return true;
    }

    //添加集合c中所有元素
    public boolean addAll(Collection c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

    //删除集合c中所有元素(如果存在的话)
    public boolean removeAll(Collection c) {
        boolean modified = false;
        Iterator it = iterator();
        while (it.hasNext()) {
            if (c.contains(it.next())) {
                it.remove();
                modified = true;
            }
        }
        return modified;
    }

    //清空
    public void clear() {
        Iterator it = iterator();
        while (it.hasNext()) {
            it.next();
            it.remove();
        }
    }

    //将集合元素显示成[String]
    public String toString() {
        Iterator it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

}

5. AbstractList

        AbstractList的定义如下:

public abstract class AbstractList extends AbstractCollection implements List {}

        从定义中可以看出,AbstractList是一个继承AbstractCollection,并且实现了List接口的抽象类。它实现了List中除了size()、get(int location)之外的方法。

        AbstractList的主要作用:它实现了List接口中的大部分函数,从而方便其它类继承List。另外,和AbstractCollection相比,AbstractList抽象类中,实现了iterator()方法。

        AbstractList抽象类的源码如下:

public abstract class AbstractList extends AbstractCollection implements List {
    
    protected AbstractList() {
    }

    public boolean add(E e) {
        add(size(), e);
        return true;
    }

    abstract public E get(int index);
    
    public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

/***************************** Search Operations**********************************/
    public int indexOf(Object o) { //搜索对象o的索引
        ListIterator it = listIterator();
        if (o==null) {
            while (it.hasNext())
                if (it.next()==null) //执行it.next(),会先返回it指向位置的值,然后it会移到下一个位置
                    return it.previousIndex(); //所以要返回it.previousIndex(); 关于it几个方法的源码在下面
        } else {
            while (it.hasNext())
                if (o.equals(it.next()))
                    return it.previousIndex();
        }
        return -1;
    }

    public int lastIndexOf(Object o) {
        ListIterator it = listIterator(size());
        if (o==null) {
            while (it.hasPrevious())
                if (it.previous()==null)
                    return it.nextIndex();
        } else {
            while (it.hasPrevious())
                if (o.equals(it.previous()))
                    return it.nextIndex();
        }
        return -1;
    }
/**********************************************************************************/

/****************************** Bulk Operations ***********************************/
    public void clear() {
        removeRange(0, size());
    }

    public boolean addAll(int index, Collection c) {
        rangeCheckForAdd(index);
        boolean modified = false;
        for (E e : c) {
            add(index++, e);
            modified = true;
        }
        return modified;
    }

	protected void removeRange(int fromIndex, int toIndex) {
        ListIterator it = listIterator(fromIndex);
        for (int i=0, n=toIndex-fromIndex; i iterator() {
        return new Itr();
    }

    public ListIterator listIterator() {
        return listIterator(0); //返回的iterator索引从0开始
    }

    public ListIterator listIterator(final int index) {
        rangeCheckForAdd(index); //首先检查index范围是否正确

        return new ListItr(index); //ListItr继承与Itr且实现了ListIterator接口,Itr实现了Iterator接口,往下看
    }

    private class Itr implements Iterator {		
        int cursor = 0; //元素的索引,当调用next()方法时,返回当前索引的值
        int lastRet = -1; //lastRet也是元素的索引,但如果删掉此元素,该值置为-1
		 /*
		 *迭代器都有个modCount值,在使用迭代器的时候,如果使用remove,add等方法的时候都会修改modCount,
		 *在迭代的时候需要保持单线程的唯一操作,如果期间进行了插入或者删除,modCount就会被修改,迭代器就会检测到被并发修改,从而出现运行时异常。
		 *举个简单的例子,现在某个线程正在遍历一个List,另一个线程对List中的某个值做了删除,那原来的线程用原来的迭代器当然无法正常遍历了
		 */
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size(); //当索引值和元素个数相同时表示没有下一个元素了,索引是从0到size-1
        }

        public E next() {
            checkForComodification(); //检查modCount是否改变
            try {
                int i = cursor; //next()方法主要做了两件事:
                E next = get(i); 
                lastRet = i;
                cursor = i + 1; //1.将索引指向了下一个位置
                return next; //2. 返回当前索引的值
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

        public void remove() {
            if (lastRet < 0) //lastRet<0表示已经不存在了
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.remove(lastRet);
                if (lastRet < cursor)
                    cursor--; //原位置的索引值减小了1,但是实际位置没变
                lastRet = -1; //置为-1表示已删除
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

    private class ListItr extends Itr implements ListIterator {
        ListItr(int index) {
            cursor = index;
        }

        public boolean hasPrevious() {
            return cursor != 0;
        }

        public E previous() {
            checkForComodification();
            try {
                int i = cursor - 1; //previous()方法中也做了两件事:
                E previous = get(i); //1. 将索引向前移动一位
                lastRet = cursor = i; //2. 返回索引处的值
                return previous;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

        public int nextIndex() { //iterator中的index本来就是下一个位置,在next()方法中可以看出
            return cursor;
        }

        public int previousIndex() {
            return cursor-1;
        }

        public void set(E e) { //修改当前位置的元素
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.set(lastRet, e);
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        public void add(E e) { //在当前位置添加元素
            checkForComodification();

            try {
                int i = cursor;
                AbstractList.this.add(i, e);
                lastRet = -1;
                cursor = i + 1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }
/**********************************************************************************/

    //获得子List,详细源码往下看SubList类
    public List subList(int fromIndex, int toIndex) {
        return (this instanceof RandomAccess ?
                new RandomAccessSubList<>(this, fromIndex, toIndex) :
                new SubList<>(this, fromIndex, toIndex));
    }

/*************************** Comparison and hashing *******************************/
    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof List))
            return false;

        ListIterator e1 = listIterator();
        ListIterator e2 = ((List) o).listIterator();
        while (e1.hasNext() && e2.hasNext()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        return !(e1.hasNext() || e2.hasNext());
    }

    public int hashCode() { //hashcode
        int hashCode = 1;
        for (E e : this)
            hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
        return hashCode;
    }
/**********************************************************************************/ 
    protected transient int modCount = 0;

    private void rangeCheckForAdd(int index) {
        if (index < 0 || index > size())
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size();
    }
}

class SubList extends AbstractList {
    private final AbstractList l;
    private final int offset;
    private int size;
	/* 从SubList源码可以看出,当需要获得一个子List时,底层并不是真正的返回一个子List,还是原来的List,只不过
	* 在操作的时候,索引全部限定在用户所需要的子List部分而已
	*/
    SubList(AbstractList list, int fromIndex, int toIndex) {
        if (fromIndex < 0)
            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
        if (toIndex > list.size())
            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
        if (fromIndex > toIndex)
            throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                               ") > toIndex(" + toIndex + ")");
        l = list; //原封不动的将原来的list赋给l
        offset = fromIndex; //偏移量,用在操作新的子List中
        size = toIndex - fromIndex; //子List的大小,所以子List中不包括toIndex处的值,即子List中包括左边不包括右边
        this.modCount = l.modCount;
    }
	//注意下面所有的操作都在索引上加上偏移量offset,相当于在原来List的副本上操作子List
    public E set(int index, E element) {
        rangeCheck(index);
        checkForComodification();
        return l.set(index+offset, element);
    }

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

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

    public void add(int index, E element) {
        rangeCheckForAdd(index);
        checkForComodification();
        l.add(index+offset, element);
        this.modCount = l.modCount;
        size++;
    }

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

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

    public boolean addAll(Collection c) {
        return addAll(size, c);
    }

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

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

    public Iterator iterator() {
        return listIterator();
    }

    public ListIterator listIterator(final int index) {
        checkForComodification();
        rangeCheckForAdd(index);

        return new ListIterator() {
            private final ListIterator i = l.listIterator(index+offset); //相当子List的索引0

            public boolean hasNext() {
                return nextIndex() < size;
            }

            public E next() {
                if (hasNext())
                    return i.next();
                else
                    throw new NoSuchElementException();
            }

            public boolean hasPrevious() {
                return previousIndex() >= 0;
            }

            public E previous() {
                if (hasPrevious())
                    return i.previous();
                else
                    throw new NoSuchElementException();
            }

            public int nextIndex() {
                return i.nextIndex() - offset;
            }

            public int previousIndex() {
                return i.previousIndex() - offset;
            }

            public void remove() {
                i.remove();
                SubList.this.modCount = l.modCount;
                size--;
            }

            public void set(E e) {
                i.set(e);
            }

            public void add(E e) {
                i.add(e);
                SubList.this.modCount = l.modCount;
                size++;
            }
        };
    }

    public List subList(int fromIndex, int toIndex) {
        return new SubList<>(this, fromIndex, toIndex);
    }

    private void rangeCheck(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private void rangeCheckForAdd(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }

    private void checkForComodification() {
        if (this.modCount != l.modCount)
            throw new ConcurrentModificationException();
    }
}

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

    public List subList(int fromIndex, int toIndex) {
        return new RandomAccessSubList<>(this, fromIndex, toIndex);
    }
}

6. AbstractSet

        AbstractSet的定义如下:

public abstract class AbstractSet extends AbstractCollection implements Set {}

        AbstractSet是一个继承与AbstractCollection,并且实现了Set接口的抽象类。由于Set接口和Collection接口中的API完全一样,所以Set也就没有自己单独的API。和AbstractCollection一样,它实现了List中除iterator()和size()外的方法。所以源码和AbstractCollection的一样。
        AbstractSet的主要作用:它实现了Set接口总的大部分函数,从而方便其他类实现Set接口。

7. Iterator

        Iterator的定义如下:

public interface Iterator {}

        Iterator是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历其中的元素。Iterator提供的API接口包括:是否存在下一个元素,获取下一个元素和删除当前元素。

        注意:Iterator遍历Collection时,是fail-fast机制的。即,当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了,那么线程A访问集合时,就会抛出CurrentModificationException异常,产生fail-fast事件。下面是Iterator的几个API。

// Iterator的API
abstract boolean hasNext()
abstract E next()
abstract void remove()

8. ListIterator

        ListIterator的定义如下:

public interface ListIterator extends Iterator {}

        ListIterator是一个继承Iterator的接口,它是队列迭代器。专门用于遍历List,能提供向前和向后遍历。相比于Iterator,它新增了添加、是否存在上一个元素、获取上一个元素等API接口:

 

// 继承于Iterator的接口
abstract boolean hasNext()
abstract E next()
abstract void remove()
// 新增API接口
abstract void add(E object)
abstract boolean hasPrevious()
abstract int nextIndex()
abstract E previous()
abstract int previousIndex()
abstract void set(E object)

Collection的架构就讨论到这吧,如果有问题欢迎留言指正~

文末福利:“程序员私房菜”,一个有温度的公众号~ 

 程序员私房菜

_____________________________________________________________________________________________________________________________________________________

-----乐于分享,共同进步!

-----更多文章请看:http://blog.csdn.net/eson_15
 

你可能感兴趣的:(●,编程语言,------【Java进阶】,Java进阶)