TreeMap

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()方法获取节点值,但不能修改
  • 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;
      }
      
  • 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();
          }
      }
      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值