TreeMap【待补充】
-
TreeMap的Entry相关函数
- firstEntry()、lastEntry()、lowerEntry()、higherEntry()、floorEntry()、 ceilingEntry()、 pollFirstEntry() 、 pollLastEntry()
- 举例:firstEntry() 和 getFirstEntry()【都是用于获得第一个节点】
- firstEntry()是对外接口、getFirstEntry()是内部接口
- 可防止用户修改返回的Entry
- 源码
// 1、getFirstEntry()返回Entry节点,而Entry是红黑树的节点 // 返回“红黑树的第一个节点” final Entry<K,V> getFirstEntry() { Entry<K,V> p = root; if (p != null) while (p.left != null) p = p.left; return p; } // 2、firstEntry()返回的是exportEntry(getFirstEntry()) static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) { return e == null? null : new AbstractMap.SimpleImmutableEntry<K,V>(e); } // 3、exportEntry() 是新建一个AbstractMap.SimpleImmutableEntry类型的对象,并返回 // SimpleImmutableEntry的实现在AbstractMap.java public static class SimpleImmutableEntry<K,V> implements Entry<K,V>, java.io.Serializable { private static final long serialVersionUID = 7138329143949025153L; private final K key; private final V value; public SimpleImmutableEntry(K key, V value) { this.key = key; this.value = value; } public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) { this.key = entry.getKey(); this.value = entry.getValue(); } public K getKey() { return key; } public V getValue() { return value; } public V setValue(V value) { throw new UnsupportedOperationException(); } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e = (Map.Entry)o; return eq(key, e.getKey()) && eq(value, e.getValue()); } public int hashCode() { return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); } public String toString() { return key + "=" + value; } }
- 总结
- SimpleImmutableEntry实际上是简化的key-value节点
- 只提供getkey()、getValue()方法获取节点值,但不能修改
- firstEntry()、lastEntry()、lowerEntry()、higherEntry()、floorEntry()、 ceilingEntry()、 pollFirstEntry() 、 pollLastEntry()
-
TreeMap的key相关函数
- firstKey()、lastKey()、lowerKey()、higherKey()、floorKey()、ceilingKey()
- ceilingKey(K key):返回大于/等于key的最小键值所对应的key
- ceilingKey()是通过getCeilingEntry()实现的。keyOrNull()的代码很简单,它是获取节点的key,没有的话,返回null
- getCeilingEntry(K key):获取TreeMap中大于/等于key的最小的节点,没有则返回null
- 源码
public K ceilingKey(K key) { return keyOrNull(getCeilingEntry(key)); } static <K,V> K keyOrNull(TreeMap.Entry<K,V> e) { return e == null? null : e.key; } final Entry<K,V> getCeilingEntry(K key) { Entry<K,V> p = root; while (p != null) { int cmp = compare(key, p.key); // 情况一:若“p的key” > key。 // 若 p 存在左孩子,则设 p=“p的左孩子”; // 否则,返回p if (cmp < 0) { if (p.left != null) p = p.left; else return p; // 情况二:若“p的key” < key。 } else if (cmp > 0) { // 若 p 存在右孩子,则设 p=“p的右孩子” if (p.right != null) { p = p.right; } else { // 若 p 不存在右孩子,则找出 p 的后继节点,并返回 // 注意:这里返回的 “p的后继节点”有2种可能性:第一,null;第二,TreeMap中大于key的最小的节点。 // 理解这一点的核心是,getCeilingEntry是从root开始遍历的。 // 若getCeilingEntry能走到这一步,那么,它之前“已经遍历过的节点的key”都 > key。 // 能理解上面所说的,那么就很容易明白,为什么“p的后继节点”有2种可能性了。 Entry<K,V> parent = p.parent; Entry<K,V> ch = p; while (parent != null && ch == parent.right) { ch = parent; parent = parent.parent; } return parent; } // 情况三:若“p的key” = key。 } else return p; } return null; }
- firstKey()、lastKey()、lowerKey()、higherKey()、floorKey()、ceilingKey()
-
TreeMap的values()函数
- values():返回TreeMap中值的集合
- values()通过 new Values() 来实现返回TreeMap中值的集合
- Values继承于AbstractCollection
- 源码
public Collection<V> values() { Collection<V> vs = values; return (vs != null) ? vs : (values = new Values()); } // TreeMap的值的集合对应的类,它集成于AbstractCollection class Values extends AbstractCollection<V> { // 返回迭代器 public Iterator<V> iterator() { return new ValueIterator(getFirstEntry()); } // 返回个数 public int size() { return TreeMap.this.size(); } // "TreeMap的值的集合"中是否包含"对象o" public boolean contains(Object o) { return TreeMap.this.containsValue(o); } // 删除"TreeMap的值的集合"中的"对象o" public boolean remove(Object o) { for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) { if (valEquals(e.getValue(), o)) { deleteEntry(e); return true; } } return false; } // 清空删除"TreeMap的值的集合" public void clear() { TreeMap.this.clear(); } }
- values():返回TreeMap中值的集合