JDK容器与并发—Map—TreeMap

来源:互联网 发布:局域网共享端口开启 编辑:程序博客网 时间:2024/05/29 16:43

概述

      基于红黑树的NavigableMap,非线程安全。

1)containsKey、get、put、remove操作的时间复杂度为log(n);

2)迭代器fail-fast。

数据结构

      红黑树:

private transient Entry<K,V> root = null; // 根节点// tree节点static final class Entry<K,V> implements Map.Entry<K,V> {K key;V value;Entry<K,V> left = null;Entry<K,V> right = null;Entry<K,V> parent;boolean color = BLACK;/** * Make a new cell with given key, value, and parent, and with * {@code null} child links, and BLACK color. */Entry(K key, V value, Entry<K,V> parent) {this.key = key;this.value = value;this.parent = parent;}/** * Returns the key. * * @return the key */public K getKey() {return key;}/** * Returns the value associated with the key. * * @return the value associated with the key */public V getValue() {return value;}/** * Replaces the value currently associated with the key with the given * value. * * @return the value associated with the key before this method was *         called */public V setValue(V value) {V oldValue = this.value;this.value = value;return oldValue;}public boolean equals(Object o) {if (!(o instanceof Map.Entry))return false;Map.Entry<?,?> e = (Map.Entry<?,?>)o;return valEquals(key,e.getKey()) && valEquals(value,e.getValue());}public int hashCode() {int keyHash = (key==null ? 0 : key.hashCode());int valueHash = (value==null ? 0 : value.hashCode());return keyHash ^ valueHash;}public String toString() {return key + "=" + value;}}

构造器

// 无参构造public TreeMap() {comparator = null;}// 带comparator构造public TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}// 带Map构造public TreeMap(Map<? extends K, ? extends V> m) {comparator = null;putAll(m);}// 带SortedMap构造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) {}}

增删改查

基础方法

// 根据key排序,获取第一个Entry// TreeMap为空则返回nullfinal Entry<K,V> getFirstEntry() {Entry<K,V> p = root; // 从根节点开始if (p != null)while (p.left != null)p = p.left; // 一直往左子树找return p;}// 根据key排序,获取最后一个Entry// TreeMap为空则返回nullfinal Entry<K,V> getLastEntry() {Entry<K,V> p = root;if (p != null)while (p.right != null)p = p.right;return p;}// 获取key关联的Entry,没有则返回nullfinal Entry<K,V> getEntry(Object key) {// Offload comparator-based version for sake of performanceif (comparator != null)return getEntryUsingComparator(key);if (key == null)throw new NullPointerException();Comparable<? super K> k = (Comparable<? super K>) key;Entry<K,V> p = root;while (p != null) {int cmp = k.compareTo(p.key);if (cmp < 0)p = p.left;else if (cmp > 0)p = p.right;elsereturn p;}return null;}// 获取>=key最小的Enntryfinal Entry<K,V> getCeilingEntry(K key) {Entry<K,V> p = root;while (p != null) {int cmp = compare(key, p.key);if (cmp < 0) {if (p.left != null)p = p.left;elsereturn p;} else if (cmp > 0) {if (p.right != null) {p = p.right;} else {Entry<K,V> parent = p.parent;Entry<K,V> ch = p;while (parent != null && ch == parent.right) {ch = parent;parent = parent.parent;}return parent;}} elsereturn p;}return null;}// 获取<=key最大的Enntryfinal Entry<K,V> getFloorEntry(K key) {Entry<K,V> p = root;while (p != null) {int cmp = compare(key, p.key);if (cmp > 0) {if (p.right != null)p = p.right;elsereturn p;} else if (cmp < 0) {if (p.left != null) {p = p.left;} else {Entry<K,V> parent = p.parent;Entry<K,V> ch = p;while (parent != null && ch == parent.left) {ch = parent;parent = parent.parent;}return parent;}} elsereturn p;}return null;}// 获取>key最小的Enntryfinal Entry<K,V> getHigherEntry(K key) {Entry<K,V> p = root;while (p != null) {int cmp = compare(key, p.key);if (cmp < 0) {if (p.left != null)p = p.left;elsereturn p;} else {if (p.right != null) {p = p.right;} else {Entry<K,V> parent = p.parent;Entry<K,V> ch = p;while (parent != null && ch == parent.right) {ch = parent;parent = parent.parent;}return parent;}}}return null;}// 获取<key最大的Enntryfinal Entry<K,V> getLowerEntry(K key) {Entry<K,V> p = root;while (p != null) {int cmp = compare(key, p.key);if (cmp > 0) {if (p.right != null)p = p.right;elsereturn p;} else {if (p.left != null) {p = p.left;} else {Entry<K,V> parent = p.parent;Entry<K,V> ch = p;while (parent != null && ch == parent.left) {ch = parent;parent = parent.parent;}return parent;}}}return null;}// 将Entry封装成不可变的SimpleImmutableEntrystatic <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {return (e == null) ? null :new AbstractMap.SimpleImmutableEntry<>(e);}// 查找指定Entry的后继节点static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {if (t == null)return null;else if (t.right != null) {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;}}// 查找指定Entry的前驱节点static <K,V> Entry<K,V> predecessor(Entry<K,V> t) {if (t == null)return null;else if (t.left != null) {Entry<K,V> p = t.left;while (p.right != null)p = p.right;return p;} else {Entry<K,V> p = t.parent;Entry<K,V> ch = t;while (p != null && ch == p.left) {ch = p;p = p.parent;}return p;}}private static <K,V> boolean colorOf(Entry<K,V> p) {return (p == null ? BLACK : p.color);}private static <K,V> Entry<K,V> parentOf(Entry<K,V> p) {return (p == null ? null: p.parent);}private static <K,V> void setColor(Entry<K,V> p, boolean c) {if (p != null)p.color = c;}private static <K,V> Entry<K,V> leftOf(Entry<K,V> p) {return (p == null) ? null: p.left;}private static <K,V> Entry<K,V> rightOf(Entry<K,V> p) {return (p == null) ? null: p.right;}// 左旋转private void rotateLeft(Entry<K,V> p) {if (p != null) {Entry<K,V> r = p.right;p.right = r.left;if (r.left != null)r.left.parent = p;r.parent = p.parent;if (p.parent == null)root = r;else if (p.parent.left == p)p.parent.left = r;elsep.parent.right = r;r.left = p;p.parent = r;}}// 右旋转private void rotateRight(Entry<K,V> p) {if (p != null) {Entry<K,V> l = p.left;p.left = l.right;if (l.right != null) l.right.parent = p;l.parent = p.parent;if (p.parent == null)root = l;else if (p.parent.right == p)p.parent.right = l;else p.parent.left = l;l.right = p;p.parent = l;}}

增、改

      步骤:
1)从root节点开始,基于key的排序比较,进行查找;
2)若已存在相等key的键值对节点,则替换新的value,返回旧value;
3)否则,根据key、value创建新节点,将其添加到TreeMap中来;
4)因有新节点添加,所以需保持红黑树平衡。

public V put(K key, V value) {Entry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}int cmp;Entry<K,V> parent;// split comparator and comparable pathsComparator<? 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;elsereturn t.setValue(value);} while (t != null);}else {if (key == null)throw new NullPointerException();Comparable<? super K> k = (Comparable<? super K>) key;do {parent = t;cmp = k.compareTo(t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}// 根据key、value创建新节点,添加到TreeMap中来Entry<K,V> e = new Entry<>(key, value, parent);if (cmp < 0)parent.left = e;elseparent.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;}

步骤:
1)从root节点开始,基于key的排序比较,进行查找;
2)若不存在相等key关联的键值对节点,则返回null;
3)否则,删除相等key关联的键值对节点;
4)保持红黑树平衡;
5)返回旧value。

public V remove(Object key) {Entry<K,V> p = getEntry(key);if (p == null)return null;V oldValue = p.value;deleteEntry(p);return oldValue;}/** * Delete node p, and then rebalance the tree. */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) {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.Entry<K,V> replacement = (p.left != null ? p.left : p.right);if (replacement != null) {// Link replacement to parentreplacement.parent = p.parent;if (p.parent == null)root = replacement;else if (p == p.parent.left)p.parent.left  = replacement;elsep.parent.right = replacement;// Null out links so they are OK to use by fixAfterDeletion.p.left = p.right = p.parent = null;// Fix replacementif (p.color == BLACK)fixAfterDeletion(replacement);} else if (p.parent == null) { // return if we are the only node.root = null;} else { //  No children. Use self as phantom replacement and unlink.if (p.color == BLACK)fixAfterDeletion(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;}}}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 { // symmetricEntry<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);}

步骤:
1)从root节点开始,基于key的排序比较,进行查找;
2)若不存在相等key关联的键值对节点,则返回null;
3)否则,相等key关联的键值对节点的value。

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 performanceif (comparator != null)return getEntryUsingComparator(key);if (key == null)throw new NullPointerException();Comparable<? super K> k = (Comparable<? super K>) key;Entry<K,V> p = root;while (p != null) {int cmp = k.compareTo(p.key);if (cmp < 0)p = p.left;else if (cmp > 0)p = p.right;elsereturn p;}return null;}

迭代器

      PrivateEntryIterator为基础迭代器:

abstract class PrivateEntryIterator<T> implements Iterator<T> {Entry<K,V> next;Entry<K,V> lastReturned;int expectedModCount;PrivateEntryIterator(Entry<K,V> first) {expectedModCount = modCount;lastReturned = null;next = first;}public final boolean hasNext() {return next != null;}final Entry<K,V> nextEntry() {Entry<K,V> e = next;if (e == null)throw new NoSuchElementException();if (modCount != expectedModCount)throw new ConcurrentModificationException();next = successor(e);lastReturned = e;return e;}final Entry<K,V> prevEntry() {Entry<K,V> e = next;if (e == null)throw new NoSuchElementException();if (modCount != expectedModCount)throw new ConcurrentModificationException();next = predecessor(e);lastReturned = e;return e;}public void remove() {if (lastReturned == null)throw new IllegalStateException();if (modCount != expectedModCount)throw new ConcurrentModificationException();// deleted entries are replaced by their successorsif (lastReturned.left != null && lastReturned.right != null)next = lastReturned;deleteEntry(lastReturned);expectedModCount = modCount;lastReturned = null;}}

特性

      基于红黑树的特性,实现log(n)的快速查找,当然付出的成本就是需要更大的内存空间。

0 0
原创粉丝点击