《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);