《java集合》--TreeMap、TreeSet

《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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章