java集合系列 02 Collection

java集合系列 02 Collection

概要

首先,對Collection進行說明。下面是Collection的繼承關係的主要類圖,(這裏只列舉了抽象類和接口,來說明Collection的整體結構)

Collection 整體架構圖

Collection是一個接口,它主要的倆個分支是:ListSet

ListSet都是接口,他們繼承於Collection。

List是有序隊列,這裏所說的有序隊列是指,按照什麼順序添加,可以以相同的順序取出來,List中可以有相同的元素。

Set可以和數學概念中的集合類比,Set中不允許有重複的元素。

由上面的類圖可以看出,首先抽象出了一個AbstractCollection抽象類,實現了Collection接口中的大部分方法,方便後面代碼的編寫。接着AbstractList 和 AbstractSet繼承了AbstractCollection。其中AbstraList實現了List中特有的一寫方法,AbstractSet實現了對於Set來說通用的一些方法。這樣做可以方便子類的編寫。這很好的體現了面向對象的思想。

另外要說明的一點是,Collection繼承了Iterator接口,所以每一個實現了Collection接口的類中,都可以使用迭代器遍歷。List系列的集合實現了一個特有的ListIterator接口,在這個接口中增加了一些添加,刪除等方法。

通過上面的介紹可以發現,Collection體系中的集合並不是特別的複雜,所以只要細心的理一下,還是很容易理解和使用的。java 8新增加了default方法,還有流(Stream),因爲我們關注的是集合的使用,因此在這裏就省略這部分內容。後面我會專門寫一系列的博客來講解java8中的流。

主要內容

  1. Collection 簡介

  2. List 簡介

  3. Set 簡介

  4. AbstractCollection 源碼分析

  5. AbstractList 源碼分析

  6. AbstractSet 源碼分析

  7. ListIterator

    注:Iterator 請看我的另一篇博客Iterator 和 iterable 區別

1. Collection 簡介

Collection 定義如下

public interface Collection<E> extends Iterable<E>{}

本身是一個接口,高度抽象出來集合,它包含了集合的基本操作:添加、刪除、清空、遍歷、、是否爲空、獲取大小、是否保護某元素等等。

在Java API規定,所有實現Collection接口的子類(直接子類和間接子類)都必須實現倆種構造參數:不帶參數的構造參數(爲了創建出一個空的集合類)和帶參數的構造參數(用參數創建出一個新的集合類,也就是可以轉換集合類)。

//Collection 接口
public abstract boolean add(E e)  //添加元素
public abstract boolean add(Collection<? extend E> c) //添加集合
public abstract void clear()   //清空集合
public abstract boolean contains(Object o) //判斷集合是否包含此元素
public abstract boolean containsAll(Collection<?> c)
                              //判斷集合中是否包含參數集合中所有的元素
public abstract boolean  equals(Object object)  //比較倆個是否相同
public abstract int     hashCode()   //返回hash值
public abstract boolean         isEmpty()    //是否爲空
public abstract Iterator<E>     iterator()   //返回迭代器
public abstract boolean remove(Object object)  //刪除某個元素
public abstract boolean removeAll(Collection<?> collection)  //刪除參數中的元素        
public abstract boolean retainAll(Collection?> collection)  //保留參數集合中元素
public abstract int             size()  //返回集合的大小
public abstract <T> T[]         toArray(T[] array) //返回T類型的數組
public abstract Object[]        toArray()  //返回包含集合所有元素的集,是Object類型

2. List 簡介

List 定義如下:

public interface List<E> extends Collection<E> {}

List 是一個繼承了Collection的接口,是集合的一種,是一個有序集合。List中的每一個集合都有一個索引,第一個元素的索引是0,往後的元素一次加1,List中允許有重複的元素

關於API方面。既然List是繼承於Collection接口,它自然就包含了Collection中的全部函數接口;由於List是有序隊列,它也額外的有自己的API接口。主要有“添加、刪除、獲取、修改指定位置的元素”、“獲取List中的子隊列”等。

// 相比與Collection,List新增的API:
abstract void                add(int location, E object) //在指定的位置增加元素
                              //在指定的位置開始增加元素
abstract boolean             addAll(int location, Collection<? extends E> c)
abstract E                   get(int location) //得到指定位置的元素
abstract int                 indexOf(Object object)  //返回第一個出現出現元素的索引
abstract int                 lastIndexOf(Object object) //返回最後一個出現出現元素的索引
abstract ListIterator<E>     listIterator(int location)  //從location位置開始返回
abstract ListIterator<E>     listIterator()//返回listIterator對象
abstract E                   remove(int location)
abstract E                   set(int location, E object) //替換某個位置的元素
abstract List<E>             subList(int start, int end) //返回當前List的子集

3. Set 簡介

Set的定義如下:

public interface Set<E> extends Collection<E> {}

Set是一個繼承與Collection的接口,也是集合中的一種。Set是不允許有重複元素的集合

在API上,和Collection完全一樣

4. AbstractCollection

AbstractCollection 定義如下:

public abstract class AbstractCollection<E> implements Collection<E> {}

AbstractCollection 是一個抽象類,他實現了Collection中除Iterator()和size()之外的函數

AbstractCollection的主要作用:它實現了Collection接口中的大部分函數。從而方便其它類實現Collection,比如ArrayList、LinkedList等,它們這些類想要實現Collection接口,通過繼承AbstractCollection就已經實現了大部分的接口了。

另外在集合中,很多的操作都是依賴於迭代器。而不同類型的集合迭代器的實現方式可能不同,因此實現迭代器一般都會放在子類中實現。

//對AbstractCollection的源碼分析

package java.util;
public abstract class AbstractCollection<E> implements Collection<E> {

   protected AbstractCollection() {

   }

   // 查詢操作

   //有collection的子類有不同的種類
   //因此不同種類的迭代器可能不相同,這裏就沒有實現
   public abstract Iterator<E> iterator();

   //返回當前集合的大小
   public abstract int size();

   //判斷當前集合是否爲空,
   //只要size等於0說明沒有元素
   public boolean isEmpty() {
       return size() == 0;
   }

   //由於每個集合都有迭代器,
   //因此可以通過迭代器進行遍歷,
   //然後判斷指定元素是否存在
   public boolean contains(Object o) {
       Iterator<E> it = iterator();
       if (o == null) {
           while (it.hasNext())
               if (it.next() == null)
                   return true;
       } else {
           while (it.hasNext())
               if (o.equals(it.next()))
                   return true;
       }
       return false;
   }

   //返回object類型的數組,
   public Object[] toArray() {
       // 先得到一個預期的集合大小,爲了防止在遍歷是有其他線程修改了集合
       Object[] r = new Object[size()];
       Iterator<E> it = iterator();
       for (int i = 0; i < r.length; i++) {
           if (!it.hasNext()) // 少於預期的集合大小,返回一個和新的集合大小相同數組
               return Arrays.copyOf(r, i);
           r[i] = it.next();
       }
       //如果預期的大小小於集合的size,則利用finishToArray返回這個集合最終轉換的數組
       return it.hasNext() ? finishToArray(r, it) : r;
   }

   //返回指定指定類型的數組,不是object類型的
   @SuppressWarnings("unchecked")
   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);
       Iterator<E> it = iterator();

       for (int i = 0; i < r.length; i++) {
           if (!it.hasNext()) { // 少於預期的大小
               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();
       }
       // 超過預期的集合大小
       return it.hasNext() ? finishToArray(r, it) : r;
   }

   //數組的最大長度,有虛擬機內部會在array頭部存儲一些信息,
   //因此最大長度沒有達到Integer的最大值
   private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

   //當在進行toArray操作時,集合大小發生改變,
   //則會使用下面的操作,重新分配數組的大小,並進行拷貝
   @SuppressWarnings("unchecked")
   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();
       }
       // 如果數組的實際長度和當前數組的長度不相等,則縮短當前數組的長度
       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;
   }

   // 修改集合操作

   // 添加操作
   public boolean add(E e) {
       throw new UnsupportedOperationException();
   }

   //通過迭代器移除和當前對象所匹配的元素
   //只會移除1個
   public boolean remove(Object o) {
       Iterator<E> 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;
   }

   // 批量操作

   // 判斷給定的集合是否在當前collection中都存在
   public boolean containsAll(Collection<?> c) {
       for (Object e : c)
           if (!contains(e))
               return false;
       return true;
   }

   //添加集合
   public boolean addAll(Collection<? extends E> c) {
       boolean modified = false;
       for (E e : c)
           if (add(e))
               modified = true;
       return modified;
   }

   //刪除當前集合中和參數給定集合匹配的元素
   public boolean removeAll(Collection<?> c) {
       Objects.requireNonNull(c);
       boolean modified = false;
       Iterator<?> it = iterator();
       while (it.hasNext()) {
           if (c.contains(it.next())) {
               it.remove();
               modified = true;
           }
       }
       return modified;
   }

   //保留當前集合中和參數給定集合匹配的元素
   public boolean retainAll(Collection<?> c) {
       Objects.requireNonNull(c);
       boolean modified = false;
       Iterator<E> it = iterator();
       while (it.hasNext()) {
           if (!c.contains(it.next())) {
               it.remove();
               modified = true;
           }
       }
       return modified;
   }

   //清空元素,利用迭代器裏面的remove
   //如果沒有實現這個方法
   //則拋出不支持該操作異常
   public void clear() {
       Iterator<E> it = iterator();
       while (it.hasNext()) {
           it.next();
           it.remove();
       }
   }

   //  返回當前collection元素組成的string
   public String toString() {
       Iterator<E> 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<E> extends AbstractCollection<E> implements List<E> {}

AbstractList是一個繼承於AbstractCollection,並且實現List接口的抽象類。

AbstractList的主要作用:它實現了List接口中的大部分函數。從而方便其它集合類繼承List。

另外,和AbstractCollection相比,AbstractList抽象類中,實現了iterator()接口。

有以下的方法沒有實現

1. public abstract E get(int var1)
2. public E set(int var1, E var2)
3. public void add(int var1, E var2)
4. public E remove(int var1)
package java.util;
public abstract class AbstractList<E> 
          extends AbstractCollection<E> implements List<E> {

    //當前list的修改操作次數,用於fail-fast決策
    protected transient int modCount = 0;

    protected AbstractList() {
    }

    //在末尾增加元素
    public boolean add(E var1) {
        this.add(this.size(), var1);
        return true;
    }

    //得到指定位置的元素 
    //需要子類實現
    public abstract E get(int var1);

    //替換指定位置的元素
    //如果未實現則拋出不支持操作異常
    public E set(int var1, E var2) {
        throw new UnsupportedOperationException();
    }

    //在指定位置增加元素
    //如果未實現則拋出不支持操作
    public void add(int var1, E var2) {
        throw new UnsupportedOperationException();
    }

    //移除指定位置元素
    //如果未實現,則拋出不支持操作
    public E remove(int var1) {
        throw new UnsupportedOperationException();
    }

    //搜索操作

    //利用listIterator來搜索指定元素
    //包含null類型的元素 
    //搜索不到返回 -1
    //如果有,返回第一個匹配元素的索引
    public int indexOf(Object var1) {
        ListIterator var2 = this.listIterator();
        if (var1 == null) {
            while (var2.hasNext()) {
                if (var2.next() == null) {
                    return var2.previousIndex();
                }
            }
        } else {
            while (var2.hasNext()) {
                if (var1.equals(var2.next())) {
                    return var2.previousIndex();
                }
            }
        }

        return -1;
    }

    //利用listIterator來搜索指定元素
    //包含null類型的元素 
    //搜索不到返回 -1
    //如果有,返回最後一個匹配元素的索引
    public int lastIndexOf(Object var1) {
        ListIterator var2 = this.listIterator(this.size());
        if (var1 == null) {
            while (var2.hasPrevious()) {
                if (var2.previous() == null) {
                    return var2.nextIndex();
                }
            }
        } else {
            while (var2.hasPrevious()) {
                if (var1.equals(var2.previous())) {
                    return var2.nextIndex();
                }
            }
        }

        return -1;
    }

    //清空元素
    public void clear() {
        this.removeRange(0, this.size());
    }

    //在指定位置之後添加集合
    public boolean addAll(int var1, Collection<? extends E> var2) {
        this.rangeCheckForAdd(var1);
        boolean var3 = false;

        for (Iterator var4 = var2.iterator(); var4.hasNext(); var3 = true) {
            Object var5 = var4.next();
            this.add(var1++, var5);
        }

        return var3;
    }

    //得到迭代器
    public Iterator<E> iterator() {
        return new AbstractList.Itr();
    }

    //得到list特有的ListIterator迭代器
    public ListIterator<E> listIterator() {
        return this.listIterator(0);
    }

    //從指定元素位置開始
    //創建一個新的迭代器
    public ListIterator<E> listIterator(int var1) {
        this.rangeCheckForAdd(var1);
        return new AbstractList.ListItr(var1);
    }

    public List<E> subList(int var1, int var2) {
        return (List) (this instanceof RandomAccess ? 
              new RandomAccessSubList(this, var1, var2) : 
                                  new SubList(this, var1, var2));
    }

    public boolean equals(Object var1) {
        if (var1 == this) {
            return true;
        } else if (!(var1 instanceof List)) {
            return false;
        } else {
            ListIterator var2 = this.listIterator();
            ListIterator var3 = ((List) var1).listIterator();

            while (true) {
                if (var2.hasNext() && var3.hasNext()) {
                    Object var4 = var2.next();
                    Object var5 = var3.next();
                    if (var4 == null) {
                        if (var5 == null) {
                            continue;
                        }
                    } else if (var4.equals(var5)) {
                        continue;
                    }

                    return false;
                }

                return !var2.hasNext() && !var3.hasNext();
            }
        }
    }

    public int hashCode() {
        int var1 = 1;

        Object var3;
        for (Iterator var2 = this.iterator(); var2.hasNext(); 
                  var1 = 31 * var1 + (var3 == null ? 0 : var3.hashCode())) {
            var3 = var2.next();
        }
        return var1;
    }

    protected void removeRange(int var1, int var2) {
        ListIterator var3 = this.listIterator(var1);
        int var4 = 0;

        for (int var5 = var2 - var1; var4 < var5; ++var4) {
            var3.next();
            var3.remove();
        }
    }

    //檢測添加的位置範圍是否合適
    private void rangeCheckForAdd(int var1) {
        if (var1 < 0 || var1 > this.size()) {
            throw new IndexOutOfBoundsException(this.outOfBoundsMsg(var1));
        }
    }
  //設置超出集合界限的模板消息
    private String outOfBoundsMsg(int var1) {
        return "Index: " + var1 + ", Size: " + this.size();
    }

    //藉助於Iterator實現雙向鏈表,
    private class ListItr extends AbstractList<E>.Itr implements ListIterator<E> {
        ListItr(int var2) {
            super(null);
            this.cursor = var2;
        }

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

        public E previous() {
            this.checkForComodification();

            try {
                int var1 = this.cursor - 1;
                Object var2 = AbstractList.this.get(var1);
                this.lastRet = this.cursor = var1;
                return var2;
            } catch (IndexOutOfBoundsException var3) {
                this.checkForComodification();
                throw new NoSuchElementException();
            }
        }

        public int nextIndex() {
            return this.cursor;
        }

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

        public void set(E var1) {
            if (this.lastRet < 0) {
                throw new IllegalStateException();
            } else {
                this.checkForComodification();

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

        public void add(E var1) {
            this.checkForComodification();

            try {
                int var2 = this.cursor;
                AbstractList.this.add(var2, var1);
                this.lastRet = -1;
                this.cursor = var2 + 1;
                this.expectedModCount = AbstractList.this.modCount;
            } catch (IndexOutOfBoundsException var3) {
                throw new ConcurrentModificationException();
            }
        }
    }

    // 實現list通用的迭代器,
    // 主要藉助的是外部類的兩個方法,remove(int) 和 get(int)
    private class Itr implements Iterator<E> {
        int cursor; //當前迭代器指向的位置
        int lastRet; //指向next操作的前一個元素
        int expectedModCount; //外部集合類修改集合的次數,用於fail-fast

        private Itr() {
            this.cursor = 0; //開始的位置
            this.lastRet = -1; //沒有開始進行迭代操作

            //外部集合類修改集合的次數,用於fail-fast
            this.expectedModCount = AbstractList.this.modCount;                          }

        //利用當前指向的遊標和外部類list的大小來判斷是否還有下一個元素
        public boolean hasNext() {
            return this.cursor != AbstractList.this.size();
        }

        //返回元素
        public E next() {
            //首先利用fail-fast來檢測list是否改變,
            this.checkForComodification();

            try {
                int var1 = this.cursor;
                //藉助外部集合類得到指定位置的元素
                Object var2 = AbstractList.this.get(var1);
                this.lastRet = var1;
                this.cursor = var1 + 1;
                return var2;
            } catch (IndexOutOfBoundsException var3) { //捕獲超出邊界異常

              //判斷是否是當前list被併發修改,如果是,則拋出此異常
                this.checkForComodification(); 
                throw new NoSuchElementException(); //正常拋出異常
            }
        }

        //實現Iterator 接口 的remove方法
        public void remove() {
            if (this.lastRet < 0) {
                throw new IllegalStateException();
            } else {
                this.checkForComodification();

                try {
                    //藉助外部類的remove方法進行刪除
                    AbstractList.this.remove(this.lastRet);
                    if (this.lastRet < this.cursor) { //當期那遊標減1
                        --this.cursor;
                    }
                    this.lastRet = -1;
                      //重新設置list的大小
                    this.expectedModCount = AbstractList.this.modCount; 
                } catch (IndexOutOfBoundsException var2) {
                    throw new ConcurrentModificationException();
                }
            }
        }

        // 判斷list是否已經修改,
        // 如果修改則拋出併發修改錯誤
        final void checkForComodification() {
            if (AbstractList.this.modCount != this.expectedModCount) {
                throw new ConcurrentModificationException();
            }
        }
    }
}

6 AbstractSet

AbstractSet的定義如下:

public abstract class AbstractSet<E> 
      extends AbstractCollection<E> 
          implements Set<E> {}

AbstractSet是一個繼承於AbstractCollection,並且實現Set接口的抽象類。由於Set接口和Collection接口中的API完全一樣,Set也就沒有自己單獨的API。

和AbstractCollection一樣,它實現了List中除iterator()和size()之外的函數。

AbstractSet的主要作用:它實現了Set接口中的大部分函數。從而方便其它類實現Set接口。

7 ListIterator

ListIterator的定義如下:

public interface ListIterator<E> extends Iterator<E> {}

ListIterator是一個繼承於Iterator的接口,它是隊列迭代器。專門用於便利List,能提供向前/向後遍歷。相比於Iterator,它新增了添加、是否存在上一個元素、獲取上一個元素等等API接口。

// ListIterator的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)
發佈了39 篇原創文章 · 獲贊 11 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章