《java集合》--TreeMap、TreeSet

本文深入解析了Java中的TreeMap数据结构,包括其实现原理、内部结构、构造方法、存储方式及核心操作方法等,并提供了示例代码帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《java集合》–TreeMap、TreeSet

说明:此文章基于jdk1.8

简介

数据结构

基于红黑二叉树存储

基本属性

  • private final Comparator

构造器

public TreeMap() {
  comparator = null;
}
//带comparator的构造器
public TreeMap(Comparator<? super K> comparator) {
  this.comparator = comparator;
}
//传入的是map,默认的comparator为空,将map中的所有元素添加到treeMap中
public TreeMap(Map<? extends K, ? extends V> m) {
  comparator = null;
  putAll(m);
}
//传入一个sortedMap
public TreeMap(SortedMap<K, ? extends V> m) {
  //使用参数的comparator对key值进行排序
  comparator = m.comparator();
  try {
    //遍历参数中的所有元素,按照key值得顺序添加
    buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
  } catch (java.io.IOException cannotHappen) {
  } catch (ClassNotFoundException cannotHappen) {
  }
}

存储的Entry

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;

  Entry(K key, V value, Entry<K,V> parent) {
    this.key = key;
    this.value = value;
    this.parent = parent;
  }

  public K getKey() {
    return key;
  }

  public V getValue() {
    return value;
  }

  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 V put(K key, V value) {
  Entry<K,V> t = root;
  //空map的时候将元素添加到map中
  if (t == null) {
    //比较key值
    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 (cpr != null) {
    //循环将key同map中的key值比较大小,
    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 {
    if (key == null)
      throw new NullPointerException();
    @SuppressWarnings("unchecked")
    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;
      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;
}

删除元素

获取元素

遍历

排序

总结

  • TreeMap是根据key进行排序的,它的排序和定位需要依赖比较器或覆写Comparable接口,也因此不需要key覆写hashCode方法和equals方法,就可以排除掉重复的key,而HashMap的key则需要通过覆写hashCode方法和equals方法来确保没有重复的key。

  • TreeMap的查询、插入、删除效率均没有HashMap高,一般只有要对key排序时才使用TreeMap。

  • TreeMap的key不能为null,而HashMap的key可以为null。

常用方法

TreeMap treeMap = new TreeMap();
treeMap.put("d", 1);
treeMap.put("b", 2);
treeMap.put("h", 3);
treeMap.put("a", 4);
System.out.println(treeMap.firstKey());//a
System.out.println(treeMap.firstEntry());//a=4
System.out.println(treeMap.lastKey());//h
System.out.println(treeMap.lastEntry());//h=3
System.out.println(treeMap.ceilingKey("b"));//b
System.out.println(treeMap.ceilingEntry("b"));//b=2
System.out.println(treeMap.higherKey("b"));//d
System.out.println(treeMap.higherEntry("b"));//d=1
System.out.println(treeMap.floorKey("b"));//b
System.out.println(treeMap.floorEntry("b"));//b=2
System.out.println(treeMap.lowerKey("b"));//a
System.out.println(treeMap.lowerEntry("b"));//a=4
/**
         * true:包含=的
         * false:不含=的
         */
System.out.println(treeMap.headMap("b",true));//小于b的
System.out.println(treeMap.tailMap("b"));//大于等于b的
System.out.println(treeMap.subMap("b",false, "e",true));//截取map
System.out.println(treeMap);
//弹出treeMap中的第一个
Entry pollFirstEntry = treeMap.pollFirstEntry();
Entry pollLastEntry = treeMap.pollLastEntry();
System.out.println(pollFirstEntry);
System.out.println(pollLastEntry);
System.out.println(treeMap);

treeMap.merge("b", 5, (oldValue, value)->{return oldValue;});
System.out.println(treeMap);
treeMap.put("b", 5);
System.out.println(treeMap);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值