1. 程式人生 > >Java 集合基礎知識 List/Set/Map

Java 集合基礎知識 List/Set/Map

linked 想要 n) nod java 集合 不同 factor inf 優化

一、List Set 區別

  • List 有序,可重復;
  • Set 無序,不重復;

二、List Set 實現類間區別及原理

  • Arraylist 底層實現使用Object[],數組查詢效率高

    擴容機制

     1.6采用(capacity * 3)/ 2 + 1,默認容量為10      1.7采用(capacity >> 2 + capacity)實現,位移動效率高於數學運算,右移一位等於乘以2倍    讀取速度快,寫入會涉及到擴容,所以相對較慢
  • LinkedList底層采用雙向鏈表,只記錄 first 和 last(LinkedList.Node);
    • Node記錄 E item; Node<E> next; Node<E> prev;
    • 寫入速度快,但是讀取速度相對較慢
  • HashSet 無序,不重復。
    • 去重原理:所有值保存至HashMap的key中,利用HashMap的鍵不重復原理達到去重效果;
    • ArrayList去重可采用:new ArrayList(new HastSet(list));
  • TreeSet 有序,不重復。
    • 底層采用TreeMap;

三、Map 實現原理及實現類對比

技術分享圖片

  1. HashMap 線程不安全

    1) 內部保存以數組 HashMap.Entry<K, V>[] 形式

 1 static class Entry<K, V> implements Map.entry<K, V> {
 2     final K key;
 3     V value;
 4     Entry<K, V> next;
 5     int hash;
 6 
 7     Entry(int h, K k, V v, Entry<K, V> n) {
 8         value = v;
 9         next = n;
10         key = k;
11         hash = h;
12 } 13 }

    2) 線程不安全原因:

      a 在數據操作方法上未采用synchronized同步標識,當多線程發生hash碰撞時,針對hash相等的key只會有一個能成功;

      b 如果上面情況涉及到resize擴容情況,每個線程內都會對內部數組進行重新創建,但只有一個會成功;

    3) 擴容(默認大小為16,2的四次方):

      capacity = (capacity * 2 * loadFactor)

      loadFactor:系數因子,默認為0.75,時間與空間的權衡結果

  2. Hashtable 內部原理及使用幾乎等於HashMap,不同的是 所有操作數據方法都進行了 synchronized 修飾,即同步處理,線程安全,但這導致單線程訪問情況下效率要低於HashMap;

    JDK4將Hashtable實現了Map接口,在JDK5中創建了替代類:ConcurrentHashMap(同步的HashMap)

    HashMap想要同步可以采用 java.util.Collections.synchronizeMap(hashMap)(jdk2出現);

    同理 Collections.synchronizeCollection(Collection<T> c)

      Collections.synchronizeList(List<T> list)

      Collections.synchronizeSet(Set<T> s)

      Collections.synchronizeSortedMap(SortedMap<K, V> m)

      Collections.synchronizeSortedSet(SortedSet<T> s)

待學習:

  JDK8中的優化點

Java 集合基礎知識 List/Set/Map