Java集合與Map的實現原理

集合關係圖集合關係圖

Collection

集合共有的父類接口 ,包含集合的共性方法:add、remove、Iterator、contains、clear…

迭代器 Iterator

它的作用是將各種不同集合的“判斷”與“取出”操作封裝成一個對象。每種集合都可以使用迭代器Iterator的hasNext/next/remove 來判斷和取出集合中的對象。

List

元素是有序的,並且可以重複;該集合有索引。add(index,element)、remove(index)、set(index,element)、 get(index)、indexOf(element)、subList(from,to)…

ListIterator:List迭代器,是Iterator的子類,繼承了Iterator的所有方法,並有 add\set\nextIndex等對list操作的方法。
PS:如果List需要使用Collections工具類的sort排序方法,泛型的對象必須實現Comparable接口。或者另外創建一個比較類,實現Comparator接口。

ArrayList
  • 底層的數據結構使用的是數組結構;
  • 特點:查詢速度快; 線程不同步。
  • 初始容量爲10,當超過容量時,則新建一個新的數組,長度爲原始長度+(50%+1)
LinkedList
  • 底層的數據結構使用的是鏈表結構;
  • 特點:增、刪、改的速度快;
Vector:
  • 底層是數組結構,該類型是在Java1.0出現的,而集合是在Java1.2出現的。
  • 使其實現List接口的同時,線程同步;
  • 初始容量爲10,當超過容量時,則新建一個新的數組,長度爲原始長度*2;(已被淘汰)

Set特點:

元素是無序的,並且不可以重複;

HashSet
  • 底層數據結構爲哈希表;
  • 特點:在執行增刪改查的時候,首先都是先判斷集合中對象中的hashcode方法,判斷hash值是否相同。
TreeSet
  • 底層數據結構是二叉樹;
  • 可以對Set集合中的元素進行字母排序;
  • 若存入自定義對象,對象需要實現Comparable接口的compareTo方法,實現自然比較。

Map

鍵值對的存儲,鍵唯一;基本方法:put(K key, V value)、clear()、 remove(K key)、containsValue(Object value)、contailsKey(Object key)、isEmpty()、get(Object key)、size()、values()、entrySet()、keySet()。。。

HashMap
  • 底層是哈希表的數據結構;
  • null值允許作爲鍵或值存入。
  • 初始化容量16,加載因子0.75
  • 線程不安全,效率高
Hashtable
  • 底層是哈希表的數據結構,該哈希表將鍵映射到相應的值
  • 任何非null對象都可以用作鍵或值
  • PS:用作鍵的對象必須實現HashCode方法和equals方法
  • 線程安全,效率低
TreeMap:
  • 底層是二叉樹數據結構;
  • 線程不同步;
  • 可以對集合中的鍵進行排序。

在這裏插入圖片描述


HashMap的實現原理***

HashMap的實現原理,在JDK1.7的時候,使用的是 數組 + 鏈表實現。而JDK1.8之後, 爲了提高遍歷效率,將鏈表改成了紅黑二叉樹的數據結構;

put流程如下

  1. 獲取key值的hashCode
  2. 用hashCode % size 確定數組位置 index
  3. 在指定位置中,如果爲null,則直接添加
  4. 若不爲null,遍歷鏈表匹配是否存在相同hashCode,若存在,則替換value
  5. 若不存在,則在鏈頭插入新的value
  6. 常量size自增

PS:在第1步獲取key值的hashCode之前,會判斷key是否爲null,若爲null,默認放到數組第一位table[0]裏。

get流程如下

  1. 獲取key值的hashCode
  2. 用hashCode % size 確定數組位置 index
  3. 在指定位置中,如果爲null,直接返回
  4. 若數組不爲null,則使用equals()函數匹配value返回

Map在JDK1.7之前的數據結構:

在這裏插入圖片描述

JDK1.8之後,爲了避免因hash算法導致數組某個節點積累的鏈表過長,JDK1.8修改成“當數組某個點位的鏈表長度超過8時,則修改成紅黑樹結構”

擴容

初始化長度爲16,加載因子爲0.75;即當前長度 > 16 * 0.75 時,進行擴容。擴容的長度爲 *2;再將原有的值重新hashing,放入新的數組中。

線程安全Map

常用的有Hashtable、ConcurrentHashMap兩個。兩者的區別如圖:在這裏插入圖片描述
Hashtable對整個數組都進行鎖處理,這樣極大地影響性能;
ConcurrentHashMap的實現可以對hashing之後的值相同的數組的點位進行鎖處理,極大地提高效率的同時,保證線程安全。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章