Java 容器知識整理

一圖勝千言

圖片描述
其中用綠色填充的爲經常使用的類,需重點掌握。java

接口簡介

Java容器的最上層都是以接口的形式出現,具體實現由子接口完成。舉個栗子,常見的如數組

Map<Integer,String> map = new HashMap<Integer, String>();

Iterator

迭代器,用於遍歷容器,JDK源碼以下:安全

package java.util;
import java.util.function.Consumer;
public interface Iterator<E> {
    boolean hasNext();
    E next();
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

常見用法:數據結構

Iterator iter = l.iterator();
  while(iter.hasNext()){
   String str = (String) iter.next();
   System.out.println(str);
  }

Collection

存放獨立元素的序列。Collection下又有三個子接口,List,Set,Queue。工具

List

一個有序的Collection(也稱序列),元素能夠重複。確切的講,列表一般容許知足 e1.equals(e2) 的元素對 e1 和 e2,而且若是列表自己容許 null 元素的話,一般它們容許多個 null 元素。實現List的有:ArrayList、LinkedList、Vector、Stack等。性能

Set

一個不包括重複元素(包括可變對象)的Collection,是一種無序的集合。Set不包含滿 a.equals(b) 的元素對a和b,而且最多有一個null。實現Set的接口有:EnumSet、HashSet、TreeSet等。ui

Queue

一種隊列則是雙端隊列,支持在頭、尾兩端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。另外一種是阻塞式隊列,隊列滿了之後再插入元素則會拋出異常,主要包括ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。spa

Map

存放key-value型的元素對。線程

常見容器與工具類

ArrayList

數據結構採用的是線性表,優點是訪問和查詢十分方便,但添加和刪除的時候效率很低。設計

LinkedList

數據結構採用的是鏈表,優點是刪除和添加的效率很高,但隨機訪問元素時效率較ArrayList類低。

HashSet

數據結構採用的是散列表,主要是設計用來作高性能集運算的,例如對兩個集合求交集、並集、差集等。集合中包含一組不重複出現且無特性順序的元素。其值是不可重複與無序的。

TreeSet

數據結構使用的是紅黑樹,性能上低於HashSet,用於排序。

HashMap

數據結構使用的是散列表,是最經常使用的是Collection

TreeMap

與TreeSet同理,用於排序。

Arrays、Collections

這二者能夠理解成工具類,提供一些處理容器類靜態方法,好比二分查找,排序等等。

常見的容器比較

ArrayList VS Vector

  • ArrayList在內存不夠時默認是擴展50% + 1個,Vector是默認擴展1倍。
  • Vector提供indexOf(obj, start)接口,ArrayList沒有。
  • Vector屬於線程安全級別的,可是大多數狀況下不使用Vector,由於線程安全須要更大的系統開銷。

沒特殊需求,通常用ArrayList

ArrayList VS LinkedList

  • 由於Array是基於索引(index)的數據結構,它使用索引在數組中搜索和讀取數據是很快的。Array獲取數據的時間複雜度是O(1),可是要刪除數據倒是開銷很大的,由於這須要重排數組中的全部數據。

  • 相對於ArrayList,LinkedList插入是更快的。由於LinkedList不像ArrayList同樣,不須要改變數組的大小,也不須要在數組裝滿的時候要將全部的數據從新裝入一個新的數組,這是ArrayList最壞的一種狀況,時間複雜度是O(n),而LinkedList中插入或刪除的時間複雜度僅爲O(1)。ArrayList在插入數據時還須要更新索引(除了插入數組的尾部)。

  • 相似於插入數據,刪除數據時,LinkedList也優於ArrayList。

  • LinkedList須要更多的內存,由於ArrayList的每一個索引的位置是實際的數據,而LinkedList中的每一個節點中存儲的是實際的數據和先後節點的位置。

HashTable VS HashMap

  • HashMap幾乎能夠等價於Hashtable,除了HashMap是非synchronized的,並能夠接受null(HashMap能夠接受爲null的鍵值(key)和值(value),而Hashtable則不行)。
    HashMap是非synchronized,而Hashtable是synchronized,這意味着Hashtable是線程安全的,多個線程能夠共享一個Hashtable;而若是沒有正確的同步的話,多個線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。
  • 另外一個區別是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。因此當有其它線程改變了HashMap的結構(增長或者移除元素),將會拋出ConcurrentModificationException,但迭代器自己的remove()方法移除元素則不會拋出ConcurrentModificationException異常。但這並非一個必定發生的行爲,要看JVM。這條一樣也是Enumeration和Iterator的區別。
  • 因爲Hashtable是線程安全的也是synchronized,因此在單線程環境下它比HashMap要慢。若是你不須要同步,只須要單一線程,那麼使用HashMap性能要好過Hashtable。 HashMap不能保證隨着時間的推移Map中的元素次序是不變的。
相關文章
相關標籤/搜索