天天看點

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

collection是一個接口,它主要的兩個分支是list和set。如下圖所示:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

        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對象。

        我們首先來閱讀下這些 接口和抽象類以及他們的實作類中都有哪些方法:

        collection的定義如下:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public interface collection<e> extends iterable<e> {}  

        從它的定義中可以看出,collection是一個接口。它是一個高度抽象出來的集合,包含了集合的基本操作:添加、删除、清空、周遊、是否為空、擷取大小等。

        collection接口的所有子類(直接子類和簡介子類)都必須實作2種構造函數:不帶參數的構造函數和參數為collection的構造函數。帶參數的構造函數可以用來轉換collection的類型。下面是collection接口中定義的api:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

// collection的api  

abstract boolean         add(e object)  

abstract boolean         addall(collection<? extends e> 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<e>     iterator()  

abstract boolean         remove(object object)  

abstract boolean         removeall(collection<?> collection)  

abstract boolean         retainall(collection<?> collection)  

abstract int             size()  

abstract <t> t[]         toarray(t[] array)  

abstract object[]        toarray()  

        list的定義如下:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public interface list<e> extends collection<e> {}  

        從list定義中可以看出,它繼承與collection接口,即list是集合的一種。list是有序的隊列,list中的每一個元素都有一個索引,第一個元素的索引值為0,往後的元素的索引值依次+1.,list中允許有重複的元素。

        list繼承collection自然包含了collection的所有接口,由于list是有序隊列,是以它也有自己額外的api接口。api如下:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

// 相比與collection,list新增的api:  

abstract void                add(int location, e object) //在指定位置添加元素  

abstract boolean             addall(int location, collection<? extends e> collection) //在指定位置添加其他集合中的元素  

abstract e                   get(int location) //擷取指定位置的元素  

abstract int                 indexof(object object) //獲得指定元素的索引  

abstract int                 lastindexof(object object) //從右邊的索引  

abstract listiterator<e>     listiterator(int location) //獲得iterator  

abstract listiterator<e>     listiterator()  

abstract e                   remove(int location) //删除指定位置的元素  

abstract e                   set(int location, e object) //修改指定位置的元素  

abstract list<e>             sublist(int start, int end) //擷取子list  

        set的定義如下:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public interface set<e> extends collection<e> {}  

        set也繼承與collection接口,且裡面不能有重複元素。關于api,set與collection的api完全一樣,不在贅述。

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public abstract class abstractcollection<e> implements collection<e> {}  

        abstractcollection是一個抽象類,它實作了collection中除了iterator()和size()之外的所有方法。abstractcollection的主要作用是友善其他類實作collection.,比如arraylist、linkedlist等。它們想要實作collection接口,通過內建abstractcollection就已經實作大部分方法了,再實作一下iterator()和size()即可。

        下面看一下abstractcollection實作的部分方法的源碼:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public abstract class abstractcollection<e> implements collection<e> {  

    protected abstractcollection() {  

    }  

    public abstract iterator<e> iterator();//iterator()方法沒有實作  

    public abstract int size(); //size()方法也沒有實作  

    public boolean isempty() { //檢測集合是否為空  

        return size() == 0;  

    /*檢查集合中是否包含特定對象*/  

    public boolean contains(object o) {   

        iterator<e> 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 false;  

    /*将集合轉變成數組*/  

    public object[] toarray() {  

        // estimate size of array; be prepared to see more or fewer elements  

        object[] r = new object[size()]; //建立與集合大小相同的數組  

        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> t[] toarray(t[] a) {  

        int size = size();  

        t[] r = a.length >= size ? a :  

                  (t[])java.lang.reflect.array  

                  .newinstance(a.getclass().getcomponenttype(), size);  

            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  

    private static <t> 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) {  

            while (it.hasnext()) {  

                if (it.next()==null) {  

                    it.remove();  

                if (o.equals(it.next())) {  

   <pre name="code" class="java">    // 判斷是否包含集合c中所有元素  

    public boolean containsall(collection<?> c) {  

        for (object e : c)  

            if (!contains(e))  

                return false;  

        return true;  

    //添加集合c中所有元素  

    public boolean addall(collection<? extends e> c) {  

        boolean modified = false;  

        for (e e : c)  

            if (add(e))  

                modified = true;  

        return modified;  

    //删除集合c中所有元素(如果存在的話)  

    public boolean removeall(collection<?> c) {  

        iterator<?> it = iterator();  

            if (c.contains(it.next())) {  

                it.remove();  

    //清空  

    public void clear() {  

            it.next();  

            it.remove();  

    //将集合元素顯示成[string]  

    public string tostring() {  

        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(' ');  

}  

        abstractlist的定義如下:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public abstract class abstractlist<e> extends abstractcollection<e> implements list<e> {}  

        從定義中可以看出,abstractlist是一個繼承abstractcollection,并且實作了list接口的抽象類。它實作了list中除了size()、get(int location)之外的方法。

        abstractlist的主要作用:它實作了list接口中的大部分函數,進而友善其它類繼承list。另外,和abstractcollection相比,abstractlist抽象類中,實作了iterator()方法。

        abstractlist抽象類的源碼如下:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public abstract class abstractlist<e> extends abstractcollection<e> implements list<e> {  

    protected abstractlist() {  

    public boolean add(e e) {  

        add(size(), e);  

    abstract public e get(int index);  

    public e set(int index, e element) {  

        throw new unsupportedoperationexception();  

    public void add(int index, e element) {  

    public e remove(int index) {  

/***************************** search operations**********************************/  

    public int indexof(object o) { //搜尋對象o的索引  

        listiterator<e> it = listiterator();  

                if (it.next()==null) //執行it.next(),會先傳回it指向位置的值,然後it會移到下一個位置  

                    return it.previousindex(); //是以要傳回it.previousindex(); 關于it幾個方法的源碼在下面  

                    return it.previousindex();  

        return -1;  

    public int lastindexof(object o) {  

        listiterator<e> it = listiterator(size());  

            while (it.hasprevious())  

                if (it.previous()==null)  

                    return it.nextindex();  

                if (o.equals(it.previous()))  

/**********************************************************************************/  

/****************************** bulk operations ***********************************/  

        removerange(0, size());  

    public boolean addall(int index, collection<? extends e> c) {  

        rangecheckforadd(index);  

        for (e e : c) {  

            add(index++, e);  

            modified = true;  

    protected void removerange(int fromindex, int toindex) {  

        listiterator<e> it = listiterator(fromindex);  

        for (int i=0, n=toindex-fromindex; i<n; i++) {  

/********************************* iterators **************************************/  

    public iterator<e> iterator() {  

        return new itr();  

    public listiterator<e> listiterator() {  

        return listiterator(0); //傳回的iterator索引從0開始  

    public listiterator<e> listiterator(final int index) {  

        rangecheckforadd(index); //首先檢查index範圍是否正确  

        return new listitr(index); //listitr繼承與itr且實作了listiterator接口,itr實作了iterator接口,往下看  

    private class itr implements iterator<e> {          

        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();  

                abstractlist.this.remove(lastret);  

                if (lastret < cursor)  

                    cursor--; //原位置的索引值減小了1,但是實際位置沒變  

                lastret = -1; //置為-1表示已删除  

                expectedmodcount = modcount;  

                throw new concurrentmodificationexception();  

        final void checkforcomodification() {  

            if (modcount != expectedmodcount)  

    private class listitr extends itr implements listiterator<e> {  

        listitr(int index) {  

            cursor = index;  

        public boolean hasprevious() {  

            return cursor != 0;  

        public e previous() {  

                int i = cursor - 1; //previous()方法中也做了兩件事:  

                e previous = get(i); //1. 将索引向前移動一位  

                lastret = cursor = i; //2. 傳回索引處的值  

                return previous;  

        public int nextindex() { //iterator中的index本來就是下一個位置,在next()方法中可以看出  

            return cursor;  

        public int previousindex() {  

            return cursor-1;  

        public void set(e e) { //修改目前位置的元素  

            if (lastret < 0)  

                abstractlist.this.set(lastret, e);  

            } catch (indexoutofboundsexception ex) {  

        public void add(e e) { //在目前位置添加元素  

                int i = cursor;  

                abstractlist.this.add(i, e);  

                lastret = -1;  

                cursor = i + 1;  

    //獲得子list,詳細源碼往下看sublist類  

    public list<e> 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<e> 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 !(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<e> extends abstractlist<e> {  

    private final abstractlist<e> l;  

    private final int offset;  

    private int size;  

    /* 從sublist源碼可以看出,當需要獲得一個子list時,底層并不是真正的傳回一個子list,還是原來的list,隻不過 

    * 在操作的時候,索引全部限定在使用者所需要的子list部分而已 

    */  

    sublist(abstractlist<e> 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  

        rangecheck(index);  

        checkforcomodification();  

        return l.set(index+offset, element);  

    public e get(int index) {  

        return l.get(index+offset);  

    public int size() {  

        return size;  

        l.add(index+offset, element);  

        size++;  

        e result = l.remove(index+offset);  

        size--;  

        return result;  

        l.removerange(fromindex+offset, toindex+offset);  

        size -= (toindex-fromindex);  

        return addall(size, c);  

        int csize = c.size();  

        if (csize==0)  

        l.addall(offset+index, c);  

        size += csize;  

        return listiterator();  

        return new listiterator<e>() {  

            private final listiterator<e> 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();  

            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);  

                size++;  

        };  

        return new sublist<>(this, fromindex, toindex);  

    private void rangecheck(int index) {  

        if (index < 0 || index >= size)  

        if (index < 0 || index > size)  

        return "index: "+index+", size: "+size;  

    private void checkforcomodification() {  

        if (this.modcount != l.modcount)  

            throw new concurrentmodificationexception();  

class randomaccesssublist<e> extends sublist<e> implements randomaccess {  

    randomaccesssublist(abstractlist<e> list, int fromindex, int toindex) {  

        super(list, fromindex, toindex);  

        return new randomaccesssublist<>(this, fromindex, toindex);  

        abstractset的定義如下:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public abstract class abstractset<e> extends abstractcollection<e> implements set<e> {}  

        abstractset是一個繼承與abstractcollection,并且實作了set接口的抽象類。由于set接口和collection接口中的api完全一樣,是以set也就沒有自己單獨的api。和abstractcollection一樣,它實作了list中除iterator()和size()外的方法。是以源碼和abstractcollection的一樣。

        abstractset的主要作用:它實作了set接口總的大部分函數,進而友善其他類實作set接口。

        iterator的定義如下:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public interface iterator<e> {}  

        iterator是一個接口,它是集合的疊代器。集合可以通過iterator去周遊其中的元素。iterator提供的api接口包括:是否存在下一個元素,擷取下一個元素和删除目前元素。

        注意:iterator周遊collection時,是fail-fast機制的。即,當某一個線程a通過iterator去周遊某集合的過程中,若該集合的内容被其他線程所改變了,那麼線程a通路集合時,就會抛出currentmodificationexception異常,産生fail-fast事件。下面是iterator的幾個api。

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

// iterator的api  

abstract boolean hasnext()  

abstract e next()  

abstract void remove()  

        listiterator的定義如下:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

public interface listiterator<e> extends iterator<e> {}  

        listiterator是一個繼承iterator的接口,它是隊列疊代器。專門用于周遊list,能提供向前和向後周遊。相比于iterator,它新增了添加、是否存在上一個元素、擷取上一個元素等api接口:

java集合架構02——Collection架構與源碼分析 1. Collection 2. List 3. Set 4. AbstractCollection 5. AbstractList 6. AbstractSet 7. Iterator 8. ListIterator

// 繼承于iterator的接口  

// 新增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/article/details/51139978