LinKedHashMap和TreeMap介绍
文章目錄
- 前言
- 一、LinKedHashMap源碼分析:
- 繼承關系:
- 屬性:
- 構造器:
- 私有內部類
- put 方法:
- LinKedHashMap總結
- 二、TreeMap源碼分析:
- 繼承關系:
- 屬性:
- 構造器:
- 私有內部類
- 方法:
- TreeMap總結:
前言
我們對LinKedHashMap和TreeMap研究都是基于HashMap為參考來研究一下他們獨有的特點,和維護這些特點的方法。
提示:以下是本篇文章正文內容,下面案例可供參考
一、LinKedHashMap源碼分析:
LinKedHashMap繼承自HashMap<K,V> 具有HashMap的所有特性:Key不能重復、Key value都可以為null 線程不安全
相比HashMap來說LinkedHashMap具有有序性(插入有序)
繼承關系:
public class LinkedHashMap<K,V>extends HashMap<K,V>implements Map<K,V>可以看出LinkedHashMap是基于HashMap實現的
屬性:
默認值、擴容機制都和HashMap的特征一樣
特有的屬性:
構造器:
構造器調用HashMap的構造器
新增一個構造器:
boolean型的accessOrder 用來判斷順序性
true 訪問有序 false 插入有序 默認值:false
私有內部類
Entry<K,V>內部類繼承與HashMap的內部類Node 增加了 head tail 用來保證有序性。
注釋:插入有序即 按照插入時的順序保持有序 訪問有序即訪問后將此數據移動到末尾。
put 方法:
直接使用put方法調用的是父類的put方法但在put方法里面調用的newNode方法是子類重寫的
public V put(K key, V value) {return putVal(hash(key), key, value, false, true);} inal V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;//判斷數組是否為空,為空則對tab進行擴容擴容后將新數組的長度賦值給n。if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;//判斷此hash對應的數組位置是否為Null 如果為null 用子類newNode方法賦值if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;//先判斷鏈表首位的hash和此新傳入的hash是否相等在判斷k值是否相等,相等的話將首尾p賦值給eif (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;//判斷p是否在紅黑樹上else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {//不在紅黑樹也不在首位的話遍歷鏈表for (int binCount = 0; ; ++binCount) {//如果遍歷到末尾給末尾賦值新創建的newNide;if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);//如果遍歷到鏈表長度之外的話if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}//如果hash值與鏈表中以為hash值相等或者K值相等的話退出循環if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;//更新pp = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;}//子類:Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {新建一個Entry 賦值給 P LinkedHashMap.Entry<K,V> p =new LinkedHashMap.Entry<>(hash, key, value, e);使用linkNodeLast方法對p進行重新操作(更新頭結點,尾結點和前綴后綴等屬性)linkNodeLast(p);return p;} private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {LinkedHashMap.Entry<K,V> last = tail;tail = p;//如果尾結點為null說明此鏈表之前沒有Entry<K,V>將p賦值給頭結點head// 否則更新p的前綴為之前的尾結點原來尾結點的后綴更新為Pif (last == null)head = p;else {p.before = last;last.after = p;}}LinKedHashMap總結
從上面我們可以看出LinKedHashMap相比于HashMap保證的數據的有序性,他的有序性保證是在HashMap原有的基礎上給每個數據添加了雙向鏈表來達到數據的有序性
二、TreeMap源碼分析:
TreeMap保證map的key可以大小排序,key不能為null (NullPointerException)value可以為null,key不能重復
繼承關系:
繼承AbstractMap所有方法
實現了 NavigableMap和Serializable(可序列化)接口
我們來介紹一下 NavigableMap主要作用就不分析源碼了
1. NavigableMap 繼承自 SortedMap,所以它的元素是有序的。 2. 在 SortedMap 基礎上,支持快速搜索符合條件的最近的元素。這里條件主要是指 lower(>), floor(>=), ceiling(<),higher(>)。 3. 支持逆序訪問。 descendingKeySet / descendingMap。 4. 支持獲取子集合,集合邊界元素是否包含是可配的 subMap headMap tailMap 。通過上述我們就可以知道TreeMap同樣也具備如上的功能
屬性:
public Comparator<? super K> comparator() { //比較器return comparator;}private transient Entry<K,V> root = null; //root屬性,紅黑樹的根節點,是entry類型entry節點根據key進行排序構造器:
相比于HashMap來說提供了比較器用來對數據進行排序
//空參構造器使用默認比較器 public TreeMap() {comparator = null;} //實現comparator的構造器public TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}//傳入數據的構造器 public TreeMap(Map<? extends K, ? extends V> m) {comparator = null;putAll(m);}//帶有comparator方法的類 public TreeMap(SortedMap<K, ? extends V> m) {comparator = m.comparator();try {buildFromSorted(m.size(), m.entrySet().iterator(), null, null);} catch (java.io.IOException | ClassNotFoundException cannotHappen) {}}私有內部類
相比較HashMap來說內部類Entry增加了左右孩子父節點還有顏色的屬性來實現紅黑樹儲存數據
static final class Entry<K,V> implements Map.Entry<K,V> {K key; //鍵V value; //值Entry<K,V> left; //左孩子Entry<K,V> right; //右孩子Entry<K,V> parent; //父節點boolean color = BLACK; //顏色 默認黑色Entry(K key, V value, Entry<K,V> parent) {this.key = key;this.value = value;this.parent = parent;}方法:
因為TreeMap繼承自NavigableMap的所以也具有他的一些方法:
lower(>), floor(>=), ceiling(<),higher(>) //快速查找
descendingKeySet / descendingMap //逆序訪問
subMap headMap tailMap //獲取子集合
TreeMap總結:
TreeMap底層是基于紅黑樹實現了,所以他支持快速查詢方法 并且它的構造器可傳入了比較器可以自定義數據的排序方法
總結
以上是生活随笔為你收集整理的LinKedHashMap和TreeMap介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HashMap和Hashtable的区别
- 下一篇: WeakHashMap和四种引用总结: