1. 程式人生 > >HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap區別

HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap區別

擴展性 navig shc .net ica fin details blank table

一、HashMap和TreeMap區別

1、HashMap是基於散列表實現的,時間復雜度平均能達到O(1)。

TreeMap基於紅黑樹(一種自平衡二叉查找樹)實現的,時間復雜度平均能達到O(log n)。

2、HashMap、TreeMap都繼承AbstractMap抽象類;TreeMap實現SortedMap接口,所以TreeMap是有序的!HashMap是無序的。
接口層次:
public interface SortedMap<K,V> extends Map<K,V>
public interface NavigableMap<K,V> extends SortedMap<K,V>

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

3、兩種常規Map性能
HashMap:適用於在Map中插入、刪除和定位元素。
Treemap:適用於按自然順序或自定義順序遍歷鍵(key)。

4.總結:HashMap通常比TreeMap快一點(樹和哈希表的數據結構使然),建議多使用HashMap,在需要排序的Map時候才用TreeMap。


二、HashMap和Hashtable的區別
HashMap和Hashtable都實現了Map接口,但決定用哪一個之前先要弄清楚它們之間的分別。主要的區別有:線程安全性,同步(synchronization),以及速度。

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中的元素次序是不變的。

我們能否讓HashMap同步?
HashMap可以通過下面的語句進行同步:
Map m = Collections.synchronizeMap(hashMap);

Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。


三、HashSet和HashMap的區別
HashSet是基於HashMap實現的。

[java] view plain copy
  1. public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
  2. {
  3. static final long serialVersionUID = -5024744406713321676L;
  4. private transient HashMap<E,Object> map;
  5. private static final Object PRESENT = new Object();
  6. public HashSet() {
  7. map = new HashMap<>();
  8. }
  9. public HashSet(Collection<? extends E> c) {
  10. map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
  11. addAll(c);
  12. }
  13. public boolean add(E e) {
  14. return map.put(e, PRESENT)==null;
  15. }
  16. public boolean remove(Object o) {
  17. return map.remove(o)==PRESENT;
  18. }
  19. .......
  20. }



HashMap HashSet
HashMap實現了Map接口 HashSet實現了Set接口
HashMap儲存鍵值對 HashSet僅僅存儲對象
使用put()方法將元素放入map中 使用add()方法將元素放入set中
HashMap中使用鍵對象來計算hashcode值 HashSet使用成員對象來計算hashcode值,對於兩個對象來說hashcode可能相同,所以equals()方法用來判斷對象的相等性,如果兩個對象不同的話,那麽返回false
HashMap比較快,因為是使用唯一的鍵來獲取對象 HashSet較HashMap



四、ConcurrentMap

ConcurrentHashMap 表現區別:不可以有null鍵,線程安全,原子操作。一個ConcurrentHashMap 由多個segment 組成,每個segment 包含一個Entity 的數組。這裏比HashMap 多了一個segment 類。該類繼承了ReentrantLock 類,所以本身是一個鎖。當多線程對ConcurrentHashMap 操作時,不是完全鎖住map, 而是鎖住相應的segment 。這樣提高了並發效率。缺點:當遍歷ConcurrentMap中的元素時,需要獲取所有的segment 的鎖,使用遍歷時慢。鎖的增多,占用了系統的資源。使得對整個集合進行操作的一些方法

五、LinkedHashMap是HashMap的一個子類

LinkedHashMap保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時,先得到的記錄肯定是先插入的.也可以在構造時用帶參數,按照應用次數排序。在遍歷的時候會比HashMap慢,不過有種情況例外,當HashMap容量很大,實際數據較少時,遍歷起來可能會比LinkedHashMap慢,因為LinkedHashMap的遍歷速度只和實際數據有關,和容量無關,而HashMap的遍歷速度和他的容量有關。

ConcurrentHashMap原理分析


六、java為數據結構中的映射定義了一個接口java.util.Map;它有四個實現類,分別是HashMap Hashtable LinkedHashMap 和TreeMap.

HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap區別