java基礎(chǔ)之TreeMap實現(xiàn)類全面詳解
TreeMap詳解
TreeMap是Map接口的一個實現(xiàn)類,底層基于紅黑樹的實現(xiàn),按照key的順序存儲
從繼承結(jié)構(gòu)可以看到TreeMap除了繼承了AbstractMap類,還實現(xiàn)了NavigableMap接口,而NavigableMap接口是繼承自SortedMap接口的,所以TreeMap是可以進行排序的
關(guān)鍵變量
// 比較器,根據(jù)比較器來決定TreeMap的排序,如果為空,按照key做自然排序(最小的在根節(jié)點) private final Comparator<? super K> comparator; // 根節(jié)點 private transient Entry<K,V> root; /** * The number of entries in the tree * 樹的大小 */ private transient int size = 0; /** * The number of structural modifications to the tree. * 修改次數(shù) */ private transient int modCount = 0; // Entry為TreeMap的內(nèi)部類 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; }
構(gòu)造函數(shù)
// 默認空參構(gòu)造器,比較器設(shè)置為空 public TreeMap() { comparator = null; } // 提供比較器 public TreeMap(Comparator<? super K> comparator) { this.comparator = comparator; } public TreeMap(Map<? extends K, ? extends V> m) { comparator = null; putAll(m); } public TreeMap(SortedMap<K, ? extends V> m) { comparator = m.comparator(); try { buildFromSorted(m.size(), m.entrySet().iterator(), null, null); } catch (java.io.IOException cannotHappen) { } catch (ClassNotFoundException cannotHappen) { } }
get方法
public V get(Object key) { Entry<K,V> p = getEntry(key); return (p==null ? null : p.value); } final Entry<K,V> getEntry(Object key) { // Offload comparator-based version for sake of performance if (comparator != null) return getEntryUsingComparator(key); // 從這里可以看出TreeMap的key不可以為null if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") Comparable<? super K> k = (Comparable<? super K>) key; // 獲取根節(jié)點 Entry<K,V> p = root; while (p != null) { // 判斷是根節(jié)點的左子樹還是右子樹 int cmp = k.compareTo(p.key); if (cmp < 0) p = p.left; else if (cmp > 0) p = p.right; else return p; } return null; }
put方法
public V put(K key, V value) { Entry<K,V> t = root; // 根節(jié)點為null,表示這是第一個元素 if (t == null) { // 主要是為了確保key是可排序的類,以及key不能為null compare(key, key); // type (and possibly null) check // 第三個參數(shù)為父節(jié)點的entry,根節(jié)點沒有父節(jié)點,所以為null root = new Entry<>(key, value, null); size = 1; modCount++; return null; } int cmp; Entry<K,V> parent; // split comparator and comparable paths Comparator<? super K> cpr = comparator; // 存在比較器的情況 if (cpr != null) { do { parent = t; cmp = cpr.compare(key, t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } // 不存在比較器,進行自然排序 else { // key不能為null if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") Comparable<? super K> k = (Comparable<? super K>) key; // do...while是為了找到該key所要存放的位置(找到父節(jié)點) do { parent = t; cmp = k.compareTo(t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } Entry<K,V> e = new Entry<>(key, value, parent); // 比父節(jié)點小,是左子樹 if (cmp < 0) parent.left = e; else parent.right = e; // 插入之后還要進行平衡操作 fixAfterInsertion(e); size++; modCount++; return null; } private void fixAfterInsertion(Entry<K,V> x) { x.color = RED; while (x != null && x != root && x.parent.color == RED) { if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { Entry<K,V> y = rightOf(parentOf(parentOf(x))); if (colorOf(y) == RED) { setColor(parentOf(x), BLACK); setColor(y, BLACK); setColor(parentOf(parentOf(x)), RED); x = parentOf(parentOf(x)); } else { if (x == rightOf(parentOf(x))) { x = parentOf(x); rotateLeft(x); } setColor(parentOf(x), BLACK); setColor(parentOf(parentOf(x)), RED); rotateRight(parentOf(parentOf(x))); } } else { Entry<K,V> y = leftOf(parentOf(parentOf(x))); if (colorOf(y) == RED) { setColor(parentOf(x), BLACK); setColor(y, BLACK); setColor(parentOf(parentOf(x)), RED); x = parentOf(parentOf(x)); } else { if (x == leftOf(parentOf(x))) { x = parentOf(x); rotateRight(x); } setColor(parentOf(x), BLACK); setColor(parentOf(parentOf(x)), RED); rotateLeft(parentOf(parentOf(x))); } } } root.color = BLACK; }
remove方法
public V remove(Object key) { // 獲取到該key對應(yīng)的節(jié)點 和get相同 Entry<K,V> p = getEntry(key); if (p == null) return null; V oldValue = p.value; deleteEntry(p); return oldValue; } private void deleteEntry(Entry<K,V> p) { modCount++; size--; // If strictly internal, copy successor's element to p and then make p // point to successor. // 存在兩個子樹(左子樹和右子樹) if (p.left != null && p.right != null) { // 找到與p數(shù)值最接近的節(jié)點(即右子樹的最左葉子節(jié)點) Entry<K,V> s = successor(p); p.key = s.key; p.value = s.value; p = s; } // p has 2 children // Start fixup at replacement node, if it exists. // 找到所要替代的節(jié)點 Entry<K,V> replacement = (p.left != null ? p.left : p.right); if (replacement != null) { // Link replacement to parent // 替換節(jié)點 replacement.parent = p.parent; if (p.parent == null) root = replacement; else if (p == p.parent.left) p.parent.left = replacement; else p.parent.right = replacement; // Null out links so they are OK to use by fixAfterDeletion. p.left = p.right = p.parent = null; // Fix replacement // 刪除的節(jié)點為黑色節(jié)點,需要進行平衡 if (p.color == BLACK) fixAfterDeletion(replacement); } // 此時replacement為null(表明 p沒有左子樹也沒有右子樹),如果p沒有父節(jié)點,表明該樹只有一個根節(jié)點 else if (p.parent == null) { // return if we are the only node. root = null; } // 此時replacement為null(表明 p沒有左子樹也沒有右子樹),表明該節(jié)點為葉子節(jié)點 else { // No children. Use self as phantom replacement and unlink. // 刪除的節(jié)點為黑色節(jié)點,需要進行平衡 if (p.color == BLACK) fixAfterDeletion(p); // 將p從樹中移除 if (p.parent != null) { if (p == p.parent.left) p.parent.left = null; else if (p == p.parent.right) p.parent.right = null; p.parent = null; } } } static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) { if (t == null) return null; else if (t.right != null) { // 右節(jié)點不為null,找到后繼節(jié)點(即右子樹的左葉子節(jié)點) Entry<K,V> p = t.right; while (p.left != null) p = p.left; return p; } else { Entry<K,V> p = t.parent; Entry<K,V> ch = t; while (p != null && ch == p.right) { ch = p; p = p.parent; } return p; } } private void fixAfterDeletion(Entry<K,V> x) { while (x != root && colorOf(x) == BLACK) { if (x == leftOf(parentOf(x))) { Entry<K,V> sib = rightOf(parentOf(x)); if (colorOf(sib) == RED) { setColor(sib, BLACK); setColor(parentOf(x), RED); rotateLeft(parentOf(x)); sib = rightOf(parentOf(x)); } if (colorOf(leftOf(sib)) == BLACK && colorOf(rightOf(sib)) == BLACK) { setColor(sib, RED); x = parentOf(x); } else { if (colorOf(rightOf(sib)) == BLACK) { setColor(leftOf(sib), BLACK); setColor(sib, RED); rotateRight(sib); sib = rightOf(parentOf(x)); } setColor(sib, colorOf(parentOf(x))); setColor(parentOf(x), BLACK); setColor(rightOf(sib), BLACK); rotateLeft(parentOf(x)); x = root; } } else { // symmetric Entry<K,V> sib = leftOf(parentOf(x)); if (colorOf(sib) == RED) { setColor(sib, BLACK); setColor(parentOf(x), RED); rotateRight(parentOf(x)); sib = leftOf(parentOf(x)); } if (colorOf(rightOf(sib)) == BLACK && colorOf(leftOf(sib)) == BLACK) { setColor(sib, RED); x = parentOf(x); } else { if (colorOf(leftOf(sib)) == BLACK) { setColor(rightOf(sib), BLACK); setColor(sib, RED); rotateLeft(sib); sib = leftOf(parentOf(x)); } setColor(sib, colorOf(parentOf(x))); setColor(parentOf(x), BLACK); setColor(leftOf(sib), BLACK); rotateRight(parentOf(x)); x = root; } } } setColor(x, BLACK); }
以上就是java基礎(chǔ)之TreeMap實現(xiàn)類全面詳解的詳細內(nèi)容,更多關(guān)于java TreeMap實現(xiàn)類的資料請關(guān)注腳本之家其它相關(guān)文章!

springboot+hutool批量生成二維碼壓縮導(dǎo)出功能

JPA @GeneratedValue 四種標(biāo)準用法TABLE,SEQUENCE,IDENTITY,

Java 實戰(zhàn)項目基于遺傳算法學(xué)校排課系統(tǒng)的實現(xiàn)流程

Java基礎(chǔ)之Unsafe內(nèi)存操作不安全類詳解