TreeMap
来源:互联网 发布:数据恢复 深圳 编辑:程序博客网 时间:2024/06/10 20:25
1、简介
1.1 TreeMap 简介
TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。
TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合。
TreeMap 实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。
TreeMap基于红黑树(Red-Black tree)实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
另外,TreeMap是非同步的。 它的iterator 方法返回的迭代器是fail-fastl的。
1.2TreeMap的构造函数
// 默认构造函数。使用该构造函数,TreeMap中的元素按照自然排序进行排列。TreeMap()// 创建的TreeMap包含MapTreeMap(Map$<$? extends K, ? extends V> copyFrom)// 指定Tree的比较器TreeMap(Comparator$<$? super K> comparator)// 创建的TreeSet包含copyFromTreeMap(SortedMap$<$K, ? extends V> copyFrom)
1.3 继承关系
java.lang.Object ↳ java.util.AbstractMap<K, V> ↳ java.util.TreeMap<K, V>public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable {}
1.4 类图
2、源代码
public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable{ //比较方法的对象 private final Comparator<? super K> comparator; //根节点 private transient Entry<K,V> root; //元素个数 private transient int size = 0; //默认构造 public TreeMap() { comparator = null; } //带比较对象的构造 public TreeMap(Comparator<? super K> comparator) { this.comparator = comparator; } //带子map的构造 public TreeMap(Map<? extends K, ? extends V> m) { comparator = null; putAll(m); } //带SortedMap的构造函数,SortedMap会成为TreeMap的子集 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 public boolean containsKey(Object key) { return getEntry(key) != null; } //是否包含value public boolean containsValue(Object value) { for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) if (valEquals(value, e.value)) return true; return false; } //根据key获得value public V get(Object key) { Entry<K,V> p = getEntry(key); return (p==null ? null : p.value); } //获取第一个key public K firstKey() { return key(getFirstEntry()); } // final Entry<K,V> getEntry(Object key) { // Offload comparator-based version for sake of performance if (comparator != null) //使用自定义的比较方法 return getEntryUsingComparator(key); if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") 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; else return p; } return null; } //获取TreeMap中大于或等于key的最小的节点; final Entry<K,V> getCeilingEntry(K key) { Entry<K,V> p = root; while (p != null) { int cmp = compare(key, p.key); //key < p.key if (cmp < 0) { //向左子树寻找 if (p.left != null) p = p.left; else //如果left为null 表示为当前路径的最小值 return p; //key > p.key } else if (cmp > 0) { //向右子树寻找 if (p.right != null) { p = p.right; } else { Entry<K,V> parent = p.parent; Entry<K,V> ch = p; //如果比所有元素都大,会回溯到根节点,返回null //如果一个值小于一个节点,但是又大于此节点左子树的所有值(p.right=null),则进行回溯,回溯到左节点(ch==parent.right条件),返回左节点的父节点。 //看图比较好理解 while (parent != null && ch == parent.right) { ch = parent; parent = parent.parent; } return parent; } } else //如果相同,直接返回 return p; } return null; } //与getCeilingEntry类似,就是没有key==p.key的条件 final 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; else return 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; } //插入键值 public V put(K key, V value) { Entry<K,V> t = root; //如果当前为空,将新建根节点 if (t == null) { compare(key, key); // type (and possibly null) check 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/else将找到需要插入的位置。如果存在key 替换value //如果有自定义的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; //使用默认Comparable 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); if (cmp < 0) parent.left = e; else parent.right = e; //修正红黑树 fixAfterInsertion(e); size++; modCount++; return null; } //移除节点 public V remove(Object key) { //找到节点 Entry<K,V> p = getEntry(key); if (p == null) return null; V oldValue = p.value; //删除 deleteEntry(p); return oldValue; } //返回key最小的节点 exportEntry使返回的节点不能更改 public Map.Entry<K,V> firstEntry() { return exportEntry(getFirstEntry()); } //弹出key最小的节点 public final Map.Entry<K,V> pollFirstEntry() { //找元素 TreeMap.Entry<K,V> e = subLowest(); //装饰为不可变 Map.Entry<K,V> result = exportEntry(e); if (e != null) //删除原节点 m.deleteEntry(e); return result; } //返回Key集 public Set<K> keySet() { return navigableKeySet(); } //返回Key集 public NavigableSet<K> navigableKeySet() { KeySet<K> nks = navigableKeySet; return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); } //返回节点集 public Set<Map.Entry<K,V>> entrySet() { EntrySet es = entrySet; return (es != null) ? es : (entrySet = new EntrySet()); } //包装为不可变的Entry static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) { return (e == null) ? null : new AbstractMap.SimpleImmutableEntry<>(e); } //元素节点类 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; /** * 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; } } //寻找并返回key最小的节点 final Entry<K,V> getFirstEntry() { Entry<K,V> p = root; if (p != null) while (p.left != null) p = p.left; return p; } //寻找继承者节点(比t大的最小节点) 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; } } //左旋转 /** From CLR */ 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; else p.parent.right = r; r.left = p; p.parent = r; } } //插入后修正 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; }}
2.2 遍历
public static void main(String[] args) { TreeMap map =new TreeMap(); Object key, value; //迭代器 Iterator iter = map.entrySet().iterator(); while(iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); key = (String)entry.getKey(); value = (Integer)entry.getValue(); } //foreach 推荐 for (Map.Entry<> entry: map.entrySet()) { key = entry.getKey(); value = entry.getValue(); } //key集 for (Object key1 : map.keySet()) { value = map.get(key1); } //value集 for (Object value1 : map.values()) { } }
2.3 总结
TreeMap是红黑树结构,红黑树是有序的,所以TreeMap也是有序的
TreeMap的键不能为null
TreeMap效率不如HashMap,Map需要有序的场合才使用TreeMap
使用descending*方法可以进行逆序操作
参考;http://www.cnblogs.com/skywang12345/p/3310928.html
阅读全文
0 0
- TreeMap
- TreeMap
- treeMap
- TreeMap
- TreeMap
- TreeMap
- TreeMap
- TreeMap
- TreeMap
- treemap
- treemap
- TreeMap
- TreeMap
- treemap
- -TreeMap
- TreeMap
- treemap
- TreeMap
- JAVA中的泛型
- js刷新页面
- java内部类的使用
- webpack--概念2--入口起点
- 计算机修炼之路--------JavaScript法术的学习笔记(五)之JavaScript原型
- TreeMap
- ShardedJedisPool的连接池参数如何设置
- Spring cloud sleuth
- ssh无密码登录
- html节点操作
- QDir类来实现目录的遍历
- ThriftParserError: ThriftPy does not support generating module with path in protocol 'd'
- AngularJS快速入门简介
- 【Linux】