TreeMap 简介
TreeMap 是一个有序的key-value 集合,内部通过红黑树实现;
TreeMap 继承了AbstractMap类,所以它是一个key-value集合;
TreeMap 实现了NavigableMap接口,而NavigableMap接口继承了SortedMap接口,所以它是一个有序的集合;
TreeMap 实现了Cloneable接口,所以它能被克隆;
TreeMap 实现了Serializable接口,所以它支持序列化;
TreeMap 的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n) 。
public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable
TreeMap 的属性
private final Comparator<? super K> comparator; 集合排序的排序器,如果创建map时没有指定排序器,那么集合的key必须实现Comparable接口,并重写compareTo方法;
private transient Entry<K,V> root = null; 集合存储数据的数据结构,实现是红黑树,类Entry<K,V> 有key,value,left,right,parent和color6个属性;
private transient int size = 0; 集合中元素的个数;
private transient int modCount = 0; 集合修改的次数;
TreeMap 构造方法
TreeMap 提供了4种构造方法,一个无参数和3个需要参数;
// 无参数构造器默认排序器为null;
public TreeMap() {
comparator = null;
}
// 创建一个自定义排序器的有序key-value集合;
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
public TreeMap(Map<? extends K, ? extends V> m) {
comparator = null;
}
public TreeMap(SortedMap<K, ? extends V> m) {
comparator = m.comparator();
try {
buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
} catch (java.io.IOException cannotHappen) {
} catch (ClassNotFoundException cannotHappen) {
}
}
节点Entry的实现
K key;
V value;
Entry<K,V> left;
Entry<K,V> right;
Entry<K,V> parent;
boolean color = BLACK;
TreeMap 主要方法
1、判断是否包含键为key的键值对
public boolean containsKey(Object key) {
return getEntry(key) != null;
}
2、判断是否包含值为value的键值对
public boolean containsValue(Object value) {
for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))
if (valEquals(value, e.value))
return true;
return false;
}
getFirstEntry() 为获取第一个节点(键值对),既最左边的节点;
successor(e) 获取当前节点的下一个节点;
3、获取键为key的value值
public V get(Object key) {
Entry<K,V> p = getEntry(key);
return (p==null ? null : p.value);
}
4、查找键为key的节点
final Entry<K,V> getEntry(Object key) {
if (comparator != null)
return getEntryUsingComparator(key);
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;
Entry<K,V> p = root;
while (p != null) {
int cmp = k.compareTo(p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
return null;
}
首先判断有没有自定义的排序器,如果有采用排序器的比较大小的方法比较key与当前节点的key的大小,小于当前节点的key,查找左子树,大于当前节点的key,查找右子树,相等则返回当前节点;如果没有自定义排序器,则采用key对象重写Comparable接口的compareTo方法比较key与当前节点的key的大小关系;
5、插入一个键值对
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
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;
Comparator<? super K> cpr = comparator;
if (cpr != null) {
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();
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;
}
(1)、判断根节点是否为null,若果为null,说明是个空集合,创建根节点;
(2)、判断是否存在自定义的比较器,若存在,使用比较器比较key与节点可以的大小关系,否在使用key默认的比较方法(非基本数据类型通过实现接口Comparable的compareTo);
(3)、判断key与当前节点key的大小关系,若比当前节点key小,则查找当前节点的左子树;若比当前节点key大,则查找当前节点的右子树;若相等,则替换当前节点的value值,并返回当前的节点的旧值。
(4)、直到当前节点的子树为空时,此子树的位置为要插入新节点的位置,则在此位置添加新的节点,添加新节点后树不再是红黑树,通过fixAfterInsertion方法重新调整树的结构,使其变成一个红黑树。
6、删除键为key的节点
public V remove(Object key) {
Entry<K,V> p = getEntry(key);
if (p == null)
return null;
V oldValue = p.value;
deleteEntry(p);
return oldValue;
}
7、删除某个节点
private void deleteEntry(Entry<K,V> p) {
modCount++;
size--;
if (p.left != null && p.right != null) {
Entry<K,V> s = successor(p);
p.key = s.key;
p.value = s.value;
p = s;
}
Entry<K,V> replacement = (p.left != null ? p.left : p.right);
if (replacement != null) {
replacement.parent = p.parent;
if (p.parent == null)
root = replacement;
else if (p == p.parent.left)
p.parent.left = replacement;
else
p.parent.right = replacement;
p.left = p.right = p.parent = null;
if (p.color == BLACK)
fixAfterDeletion(replacement);
} else if (p.parent == null) {
root = null;
} else {
if (p.color == BLACK)
fixAfterDeletion(p);
if (p.parent != null) {
if (p == p.parent.left)
p.parent.left = null;
else if (p == p.parent.right)
p.parent.right = null;
p.parent = null;
}
}
}
8、获取第一个key或最后一个key
public K firstKey() {
return key(getFirstEntry());
}
public K lastKey() {
return key(getLastEntry());
}
9、克隆一个map
public Object clone() {
TreeMap<?,?> clone;
try {
clone = (TreeMap<?,?>) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
clone.root = null;
clone.size = 0;
clone.modCount = 0;
clone.entrySet = null;
clone.navigableKeySet = null;
clone.descendingMap = null;
try {
clone.buildFromSorted(size, entrySet().iterator(), null, null);
} catch (java.io.IOException cannotHappen) {
} catch (ClassNotFoundException cannotHappen) {
}
return clone;
}
10、获取第一个键值对和最后一个键值对
public Map.Entry<K,V> firstEntry() {
return exportEntry(getFirstEntry());
}
public Map.Entry<K,V> lastEntry() {
return exportEntry(getLastEntry());
}
11、poll第一个键值对和最后一个键值对
public Map.Entry<K,V> pollFirstEntry() {
Entry<K,V> p = getFirstEntry();
Map.Entry<K,V> result = exportEntry(p);
if (p != null)
deleteEntry(p);
return result;
}
public Map.Entry<K,V> pollLastEntry() {
Entry<K,V> p = getLastEntry();
Map.Entry<K,V> result = exportEntry(p);
if (p != null)
deleteEntry(p);
return result;
}
12、如果map集合中存在键值对的key==key,则返回此键值对;如果不存在,在返回比key第一大的键值对
public Map.Entry<K,V> ceilingEntry(K key) {
return exportEntry(getCeilingEntry(key));
}
public K ceilingKey(K key) {
return keyOrNull(getCeilingEntry(key));
}
final Entry<K,V> getCeilingEntry(K key) {
Entry<K,V> p = root;
while (p != null) {
int cmp = compare(key, p.key);
if (cmp < 0) {
if (p.left != null)
p = p.left;
else
return p;
} else if (cmp > 0) {
if (p.right != null) {
p = p.right;
} else {
Entry<K,V> parent = p.parent;
Entry<K,V> ch = p;
while (parent != null && ch == parent.right) {
ch = parent;
parent = parent.parent;
}
return parent;
}
} else
return p;
}
return null;
}
13、如果map集合中存在键值对的key==key,则返回此键值对;如果不存在,在返回比key第一小的键值对
public Map.Entry<K,V> floorEntry(K key) {
return exportEntry(getFloorEntry(key));
}
public K floorKey(K key) {
return keyOrNull(getFloorEntry(key));
}
14、获取比key第一小的键值对
public Map.Entry<K,V> lowerEntry(K key) {
return exportEntry(getLowerEntry(key));
}
public K lowerKey(K key) {
return keyOrNull(getLowerEntry(key));
}
15、获取比key第一大的键值对
public Map.Entry<K,V> higherEntry(K key) {
return exportEntry(getHigherEntry(key));
}
public K higherKey(K key) {
return keyOrNull(getHigherEntry(key));
}
16、返回key集合
public Set<K> keySet() {
return navigableKeySet();
}
返回有序key集合
public NavigableSet<K> navigableKeySet() {
KeySet<K> nks = navigableKeySet;
return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this));
}
返回递减有序的key集合
public NavigableSet<K> descendingKeySet() {
return descendingMap().navigableKeySet();
}
17、返回从fromKey(包括)到tokey(不包括)的键值对
public SortedMap<K,V> subMap(K fromKey, K toKey) {
return subMap(fromKey, true, toKey, false);
}
返回从第一个到key(不包括)的键值对
public SortedMap<K,V> headMap(K toKey) {
return headMap(toKey, false);
}
返回从key(包括)以后的键值对
public SortedMap<K,V> tailMap(K fromKey) {
return tailMap(fromKey, true);
}