一、类继承图
二、SortedMap接口概述和使用
SortedMap表示一个维护了key的顺序的Map,通过key本身实现的Comparable接口或者SortedMap实例初始化时指定Comparator实例来排序。如果插入的key没有实现Comparable接口,也不能被Comparator实例比较,则会抛出异ClassCastException。注意实现Comparable或者Comparator接口时,应保证与key的equals()方法保持一致,即equals()方法相等时,通过Comparable或者Comparator比较的结果也应该是相等的,因为equals()方法是Map接口判断key相等的基础。
接口包含的方法如下:
SortedMap覆写了Map接口中keySet(),values(),entrySet()的方法定义,增加了一条,要求返回的视图中的元素时按照键值K升序排序的。其他方法的使用参考示例:
public class User {
private String userName;
private Integer age;
public User() {
}
public User(String userName, Integer age) {
this.userName = userName;
this.age = age;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", age=" + age +
'}';
}
}
public class UserComp implements Comparable<UserComp> {
private String userName;
private Integer age;
public UserComp() {
}
public UserComp(String userName, Integer age) {
this.userName = userName;
this.age = age;
}
//注意此处是this-o,如果反过来排序就是降序的
public int compareTo(UserComp o) {
return this.age-o.getAge();
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", age=" + age +
'}';
}
}
@Test
public void name() throws Exception {
//String实现了Comparable接口
SortedMap<String,Integer> sortedMap=new TreeMap();
sortedMap.put("a",1);
sortedMap.put("c",1);
sortedMap.put("b",1);
for(String key:sortedMap.keySet()){
System.out.println(key+":"+sortedMap.get(key));
}
}
@Test
public void test3() throws Exception {
//初始化时提供Comparator接口实现
Comparator<User> comparator=new Comparator<User>() {
//注意如果o2-o1,结果就是降序了
public int compare(User o1, User o2) {
return o1.getAge()-o2.getAge();
}
};
SortedMap<User,Integer> sortedMap=new TreeMap(comparator);
sortedMap.put(new User("shl",12),1);
sortedMap.put(new User("shl",13),1);
sortedMap.put(new User("shl",14),1);
for(User key:sortedMap.keySet()){
System.out.println(key+":"+sortedMap.get(key));
}
}
@Test
public void test4() throws Exception {
//UserComp实现了Comparable接口
SortedMap<UserComp,Integer> sortedMap=new TreeMap();
sortedMap.put(new UserComp("shl",12),1);
sortedMap.put(new UserComp("shl",13),1);
sortedMap.put(new UserComp("shl",14),1);
for(UserComp key:sortedMap.keySet()){
System.out.println(key+":"+sortedMap.get(key));
}
}
@Test
public void test5() throws Exception {
SortedMap<Integer,String> sortedMap=new TreeMap();
sortedMap.put(1,"a");
sortedMap.put(2,"a");
sortedMap.put(3,"a");
sortedMap.put(4,"a");
sortedMap.put(5,"a");
sortedMap.put(6,"a");
//SortedMap返回子Map时都是半包含的,即包含最小值不包含最大值,NavigableMap中可以指定是否起止值
//返回大于等于1,小于4的子Map
System.out.println("========subMap========");
SortedMap<Integer,String> subMap=sortedMap.subMap(1,4);
for(Integer key:subMap.keySet()){
System.out.println(key+":"+subMap.get(key));
}
//返回小于5的子Map
System.out.println("========headMap========");
subMap=sortedMap.headMap(5);
for(Integer key:subMap.keySet()){
System.out.println(key+":"+subMap.get(key));
}
//返回大于等于2的子Map
System.out.println("========tailMap========");
subMap=sortedMap.tailMap(2);
for(Integer key:subMap.keySet()){
System.out.println(key+":"+subMap.get(key));
}
System.out.println("firstKey:"+subMap.firstKey());
System.out.println("lastKey:"+subMap.lastKey());
}
三、NavigableMap接口概述和使用
NavigableMap扩展自SortedMap,增加了一些查找目标key的快捷方法,比如lowerEntry返回小于,floorEntry返回小于或者等于, ceilingEntry返回大于或等于,higherEntry返回大于给定key的Map.Entry对象。类似的有lowerKey,floorKey,ceilingKey, higherKey返回符合条件的目标key。扩展了SortedMap的subMap,headMap,tailMap等方法,增加参数可以指定是否包含起止值,且返回的是SortedMap的升级接口NavigableMap实例。增加对降序遍历的支持,通过descendingMap()返回一个降序排序的视图,注意默认的升序视图的遍历比降序视图要快。接口包含的方法如下:
参考如下示例:
@Test
public void test() throws Exception {
NavigableMap<Integer,String> sortedMap=new TreeMap();
sortedMap.put(1,"a");
sortedMap.put(2,"a");
sortedMap.put(3,"a");
sortedMap.put(4,"a");
sortedMap.put(5,"a");
sortedMap.put(6,"a");
//小于指定key的最大的一个key
Map.Entry<Integer,String> entry=sortedMap.lowerEntry(3);
System.out.println(entry);
//小于或等于指定key的最大的一个key
entry=sortedMap.floorEntry(3);
System.out.println(entry);
//大于指定key的最小的一个key
entry=sortedMap.higherEntry(3);
System.out.println(entry);
//大于等于指定key的最小的一个key
entry=sortedMap.ceilingEntry(3);
System.out.println(entry);
//返回并移除第一个元素
Map.Entry first=sortedMap.pollFirstEntry();
System.out.println(first.getKey());
//返回并移除最后一个元素
Map.Entry last=sortedMap.pollLastEntry();
System.out.println(last.getKey());
//表示不包含2,包含5
NavigableMap<Integer,String> subMap= sortedMap.subMap(2,false,5 ,true);
for(Integer key:subMap.keySet()){
System.out.println("key="+key+",value="+subMap.get(key));
}
}
@Test
public void test2() throws Exception {
NavigableMap<Integer,String> sortedMap=new TreeMap();
sortedMap.put(1,"a");
sortedMap.put(2,"a");
sortedMap.put(3,"a");
sortedMap.put(4,"a");
sortedMap.put(5,"a");
sortedMap.put(6,"a");
//默认是升序
for(Integer key:sortedMap.keySet()){
System.out.println(key+":"+sortedMap.get(key));
}
//返回降序排列的key视图
NavigableMap<Integer,String> desMap=sortedMap.descendingMap();
for(Integer key:desMap.keySet()){
System.out.println(key+":"+sortedMap.get(key));
}
//效果等同于descendingMap
for(Integer key:sortedMap.descendingKeySet()){
System.out.println(key+":"+sortedMap.get(key));
}
}
四、TreeMap接口实现源码解读
TreeMap是一个基于红黑树结构的NavigableMap接口实现,因为key必须可比,所以key不能是null,value可以是null。同HashMap,非线程安全,遍历时修改元素会快读失败。
1、全局属性
//用于比较K顺序,如果K实现了Comparable接口,可以为null
private final Comparator<? super K> comparator;
//红黑树的根节点
private transient Entry<K,V> root;
//节点个数
private transient int size = 0;
//修改次数
private transient int modCount = 0;
//节点颜色
private static final boolean RED = false;
private static final boolean BLACK = true;
//视图属性
private transient EntrySet entrySet;
private transient KeySet<K> navigableKeySet;
private transient NavigableMap<K,V> descendingMap;
//表示无上限的常量
private static final Object UNBOUNDED = new Object();
2、构造方法
public TreeMap() {
comparator = null;
}
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
public TreeMap(Map<? extends K, ? extends V> m) {
comparator = null;
//判断m是否是SortedMap实例,如果是利用buildFromSorted方法初始化,否则将Map中键值对逐一put到TreeMap中
putAll(m);
}
public TreeMap(SortedMap<K, ? extends V> m) {
comparator = m.comparator();
try {
//根据一个排序好的SortedMap构建红黑树
buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
} catch (java.io.IOException cannotHappen) {
} catch (ClassNotFoundException cannotHappen) {
}
}
public void putAll(Map<? extends K, ? extends V> map) {
int mapSize = map.size();
//如果当前TreeMap size为0,目标map size大于0且是SortedMap
if (size==0 && mapSize!=0 && map instanceof SortedMap) {
Comparator<?> c = ((SortedMap<?,?>)map).comparator();
//两个Map的比较器一致
if (c == comparator || (c != null && c.equals(comparator))) {
++modCount;
try {
buildFromSorted(mapSize, map.entrySet().iterator(),
null, null);
} catch (java.io.IOException cannotHappen) {
} catch (ClassNotFoundException cannotHappen) {
}
return;
}
}
//遍历map将其中的元素逐一添加到TreeMap中
super.putAll(map);
}
3、红黑树节点实现
/**
* 基于红黑树节点的键值对的标准实现
*/
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;
}
//setValue时会返回原来的值
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;
}
}
4、元素插入
public V put(K key, V value) {
Entry<K,V> t = root;
//根节点为空,即第一次插入
if (t == null) {
//判断该key是否可以比较,如果不能比较此处会抛出异常
compare(key, key);
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的节点则t为null跳出循环,parent为目标节点的父节点,cmp为跟父节点key比较的结果
do {
//从根节点开始往下遍历
parent = t;
cmp = cpr.compare(key, t.key);
//小于根节点,走左子树继续比较
if (cmp < 0)
t = t.left;
//大于根节点,走右子树继续比较
else if (cmp > 0)
t = t.right;
else
//找到key相同的,覆盖并返回原值
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);
}
//不存在相同的key,此时parent为目标key的父节点
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;
}
5、元素查找
public V get(Object key) {
Entry<K,V> p = getEntry(key);
return (p==null ? null : p.value);
}
final Entry<K,V> getEntry(Object key) {
// 基于comparator遍历红黑树
if (comparator != null)
return getEntryUsingComparator(key);
if (key == null)
throw new NullPointerException();
//如果comparator为空且K未实现Comparable接口,此处会抛出ClassCastException异常
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
//遍历红黑树查找key
Entry<K,V> p = root;
while (p != null) {
int cmp = k.compareTo(p.key);
//小于父节点的key,在左子树中继续查找
if (cmp < 0)
p = p.left;
//大于父节点的key,在右子树中继续查找
else if (cmp > 0)
p = p.right;
else
//key值相等则返回该节点
return p;
}
return null;
}
final Entry<K,V> getEntryUsingComparator(Object key) {
@SuppressWarnings("unchecked")
K k = (K) key;
Comparator<? super K> cpr = comparator;
if (cpr != null) {
//遍历红黑树查找key
Entry<K,V> p = root;
while (p != null) {
int cmp = cpr.compare(k, p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
}
return null;
}
6、范围查找
/**
* 获取TreeMap中升序排序最前的键值对
*/
final Entry<K,V> getFirstEntry() {
Entry<K,V> p = root;
if (p != null)
//遍历红黑树找到最左边的一个左节点
while (p.left != null)
p = p.left;
return p;
}
/**
* 获取TreeMap中升序排序最后的键值对
*/
final Entry<K,V> getLastEntry() {
Entry<K,V> p = root;
if (p != null)
//遍历红黑树找到最右边的一个右节点
while (p.right != null)
p = p.right;
return p;
}
/**
* 返回比t大的最小的元素
*/
static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {
if (t == null)
return null;
else if (t.right != null) {
//返回右子树中最小的元素
Entry<K,V> p = t.right;
while (p.left != null)
p = p.left;
return p;
} else {
//没有右节点,而左子树中所有节点都比当前节点小,所以只能往上遍历找比当前节点大的点
Entry<K,V> p = t.parent;
Entry<K,V> ch = t;
/
//不断往上遍历,直到当前节点为左节点为止,此时父节点的key值大于当前节点,返回该父节点
//如果当节点为最右边的节点,不断往上遍历时返回的null,即没有下一个元素
while (p != null && ch == p.right) {
ch = p;
p = p.parent;
}
return p;
}
}
/**
* 返回当前元素在排序顺序中的前一个元素,即比他小的最大的元素
*/
static <K,V> Entry<K,V> predecessor(Entry<K,V> t) {
if (t == null)
return null;
else if (t.left != null) {
//如果存在左子树,找左子树中最右边的一个节点
Entry<K,V> p = t.left;
while (p.right != null)
p = p.right;
return p;
} else {
//没有左子树,因为右子树中节点都比当前节点大,所以只能往上查找
Entry<K,V> p = t.parent;
Entry<K,V> ch = t;
//不断往上遍历,直到当前节点为右节点为止,此时父节点的key小于当前节点,返回该父节点
while (p != null && ch == p.left) {
ch = p;
p = p.parent;
}
return p;
}
}
/**
* 返回大于或者等于当前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;
//左子树为空表示没有比key更小的节点了,返回该节点
else
return p;
} else if (cmp > 0) {
//右子树不为空,遍历右子树
if (p.right != null) {
p = p.right;
} else {
//右子树为空,左子树中所有节点比当前节点小,所以只能往上查找大于key的最小元素
//不断往上遍历,直到当前节点为父节点的左节点,此时父节点的key大于目标key值,返回该父节点
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;
}
/**
返回大于目标key的最小的一个key
*/
final Entry<K,V> getHigherEntry(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 (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;
}
}
}
return null;
}
/**
* 返回小于或者等于指定key的最大的元素
*/
final Entry<K,V> getFloorEntry(K key) {
Entry<K,V> p = root;
while (p != null) {
int cmp = compare(key, p.key);
//父节点的key值小于目标节点,因为左子树的所有节点都比父节点小,所以要从右子树中查找小于或者等于目标key的最大元素
if (cmp > 0) {
//右节点不为空,继续在右子树中查找
if (p.right != null)
p = p.right;
else
//右节点没了,即当前节点是红黑树中最底层的右节点,小于key最大的一个节点
return p;
} else if (cmp < 0) {
//父节点的key值大于目标key,右子树中所有节点比父节点大,只能在左子树中查找小于或等于目标key的最大元素
if (p.left != null) {
p = p.left;
} else {
//左子树为空,只能往上遍历查找小于目标key的最大节点
Entry<K,V> parent = p.parent;
Entry<K,V> ch = p;
//一直往上遍历,直到当前节点为父节点的右节点,此时父节点的key值小于目标节点,返回该父节点
//如果一直是左节点,遍历到根节点则返回null,表示没有比目标key小的节点
while (parent != null && ch == parent.left) {
ch = parent;
parent = parent.parent;
}
return parent;
}
} else
//等于目标key值,返回该节点
return p;
}
return null;
}
/**
返回小于目标key的最大的key
*/
final Entry<K,V> getLowerEntry(K key) {
Entry<K,V> p = root;
while (p != null) {
int cmp = compare(key, p.key);
if (cmp > 0) {
if (p.right != null)
p = p.right;
else
return p;
} else {
if (p.left != null) {
p = p.left;
} else {
Entry<K,V> parent = p.parent;
Entry<K,V> ch = p;
while (parent != null && ch == parent.left) {
ch = parent;
parent = parent.parent;
}
return parent;
}
}
}
return null;
}
7、获取子Map方法
TreeMap中获取子Map的方法返回的实例都是内部实现的AscendingSubMap实例,该实例继承自了NavigableSubMap,NavigableSubMap是TreeMap实现NavigableMap接口的内部类,子Map在指定范围内遍历的核心实现在NavigableSubMap中,主要还是依赖于TreeMap中范围查找的相关方法。
abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
implements NavigableMap<K,V>, java.io.Serializable {
private static final long serialVersionUID = -2102997345730753016L;
//父级TreeMap
final TreeMap<K,V> m;
//lo,hi表示取值范围的最小值和最大值
final K lo, hi;
//fromStart为true表示不考虑起始值,从整个排序的最小值开始,toEnd为true表示不考虑终止值,一直到整个排序的最大值
final boolean fromStart, toEnd;
//loInclusive表示取值范围是否包含最小值,hiInclusive表示取值范围是否包含最大值,默认是不包含
final boolean loInclusive, hiInclusive;
NavigableSubMap(TreeMap<K,V> m,
boolean fromStart, K lo, boolean loInclusive,
boolean toEnd, K hi, boolean hiInclusive) {
//最大值和最小值都存在
if (!fromStart && !toEnd) {
//判断最大值是否大于最小值
if (m.compare(lo, hi) > 0)
throw new IllegalArgumentException("fromKey > toKey");
} else {
//存在最小值,判断该key是否可比
if (!fromStart) // type check
m.compare(lo, lo);
/存在最大值,判断该key是否可比
if (!toEnd)
m.compare(hi, hi);
}
this.m = m;
this.fromStart = fromStart;
this.lo = lo;
this.loInclusive = loInclusive;
this.toEnd = toEnd;
this.hi = hi;
this.hiInclusive = hiInclusive;
}
//是否小于最小值
final boolean tooLow(Object key) {
if (!fromStart) {
int c = m.compare(key, lo);
if (c < 0 || (c == 0 && !loInclusive))
return true;
}
return false;
}
//是否大于最小值
final boolean tooHigh(Object key) {
if (!toEnd) {
int c = m.compare(key, hi);
if (c > 0 || (c == 0 && !hiInclusive))
return true;
}
return false;
}
//判断目标key是否在取值范围内,根据loInclusive和hiInclusive判断是否包含起始值
final boolean inRange(Object key) {
return !tooLow(key) && !tooHigh(key);
}
//判断目标key是否在取值范围内,包含起始值
final boolean inClosedRange(Object key) {
return (fromStart || m.compare(key, lo) >= 0)
&& (toEnd || m.compare(hi, key) >= 0);
}
//该方法主要用于获取子Map的子Map
final boolean inRange(Object key, boolean inclusive) {
//如果inclusive为true,需要父Map是否包含目标key值,如果父Map不包含,而子Map包含则返回false
//如果inclusive为false,子Map不包含目标key值,则只需要判断目标key是否在父Map的取值范围内即可
return inclusive ? inRange(key) : inClosedRange(key);
}
//获取设定范围的最小值
final TreeMap.Entry<K,V> absLowest() {
TreeMap.Entry<K,V> e =
(fromStart ? m.getFirstEntry() :
(loInclusive ? m.getCeilingEntry(lo) :
m.getHigherEntry(lo)));
return (e == null || tooHigh(e.key)) ? null : e;
}
//获取设定范围的最大值
final TreeMap.Entry<K,V> absHighest() {
TreeMap.Entry<K,V> e =
(toEnd ? m.getLastEntry() :
(hiInclusive ? m.getFloorEntry(hi) :
m.getLowerEntry(hi)));
return (e == null || tooLow(e.key)) ? null : e;
}
//获取大于等于当前key的最小元素,如果低于最小值返回最小值
final TreeMap.Entry<K,V> absCeiling(K key) {
if (tooLow(key))
return absLowest();
TreeMap.Entry<K,V> e = m.getCeilingEntry(key);
return (e == null || tooHigh(e.key)) ? null : e;
}
//获取大于当前key的最小元素,如果低于最小值返回最小值
final TreeMap.Entry<K,V> absHigher(K key) {
if (tooLow(key))
return absLowest();
TreeMap.Entry<K,V> e = m.getHigherEntry(key);
return (e == null || tooHigh(e.key)) ? null : e;
}
//获取小于等于当前key的最小元素,如果大于最大值返回最大值
final TreeMap.Entry<K,V> absFloor(K key) {
if (tooHigh(key))
return absHighest();
TreeMap.Entry<K,V> e = m.getFloorEntry(key);
return (e == null || tooLow(e.key)) ? null : e;
}
//获取小于当前key的最小元素,如果大于最大值返回最大值
final TreeMap.Entry<K,V> absLower(K key) {
if (tooHigh(key))
return absHighest();
TreeMap.Entry<K,V> e = m.getLowerEntry(key);
return (e == null || tooLow(e.key)) ? null : e;
}
//获取设定范围的上限值
final TreeMap.Entry<K,V> absHighFence() {
return (toEnd ? null : (hiInclusive ?
m.getHigherEntry(hi) :
m.getCeilingEntry(hi)));
}
//获取设定范围的下限值
final TreeMap.Entry<K,V> absLowFence() {
return (fromStart ? null : (loInclusive ?
m.getLowerEntry(lo) :
m.getFloorEntry(lo)));
}
// View classes
abstract class EntrySetView extends AbstractSet<Map.Entry<K,V>> {
private transient int size = -1, sizeModCount;
public int size() {
if (fromStart && toEnd)
return m.size();
//未初始化
if (size == -1 || sizeModCount != m.modCount) {
sizeModCount = m.modCount;
size = 0;
//遍历计算size
Iterator<?> i = iterator();
while (i.hasNext()) {
size++;
i.next();
}
}
return size;
}
public boolean isEmpty() {
TreeMap.Entry<K,V> n = absLowest();
return n == null || tooHigh(n.key);
}
public boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
Object key = entry.getKey();
//不在范围内返回false
if (!inRange(key))
return false;
TreeMap.Entry<?,?> node = m.getEntry(key);
return node != null &&
valEquals(node.getValue(), entry.getValue());
}
public boolean remove(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
Object key = entry.getKey();
if (!inRange(key))
return false;
TreeMap.Entry<K,V> node = m.getEntry(key);
if (node!=null && valEquals(node.getValue(),
entry.getValue())) {
m.deleteEntry(node);
return true;
}
return false;
}
}
/**
* 抽象实现类
*/
abstract class SubMapIterator<T> implements Iterator<T> {
TreeMap.Entry<K,V> lastReturned;
TreeMap.Entry<K,V> next;
final Object fenceKey;
int expectedModCount;
//first和fence分别标识最小值和最大值,即在该范围内遍历
SubMapIterator(TreeMap.Entry<K,V> first,
TreeMap.Entry<K,V> fence) {
expectedModCount = m.modCount;
lastReturned = null;
next = first;
fenceKey = fence == null ? UNBOUNDED : fence.key;
}
//需要判断下一个元素是否是边界元素
public final boolean hasNext() {
return next != null && next.key != fenceKey;
}
//用于顺序遍历
final TreeMap.Entry<K,V> nextEntry() {
TreeMap.Entry<K,V> e = next;
//如果e为null或者是边界元素则抛出异常
if (e == null || e.key == fenceKey)
throw new NoSuchElementException();
if (m.modCount != expectedModCount)
throw new ConcurrentModificationException();
//找到当前元素的下一个元素
next = successor(e);
lastReturned = e;
return e;
}
//用于倒序遍历
final TreeMap.Entry<K,V> prevEntry() {
TreeMap.Entry<K,V> e = next;
//如果e为null或者是边界元素则抛出异常
if (e == null || e.key == fenceKey)
throw new NoSuchElementException();
if (m.modCount != expectedModCount)
throw new ConcurrentModificationException();
//找到当前元素的上一个元素
next = predecessor(e);
lastReturned = e;
return e;
}
//顺序遍历时移除元素
final void removeAscending() {
if (lastReturned == null)
throw new IllegalStateException();
if (m.modCount != expectedModCount)
throw new ConcurrentModificationException();
// 删除lastReturned节点时,如果该节点的左右节点都存在,则该节点实际不会删除,只是该节点的key/value会被改写成
//下一个节点的key/value,所以此时next会等于lastReturned
//如果是倒序遍历,因为下一个元素时被删除元素的上一个元素所以不存在next = lastReturned
if (lastReturned.left != null && lastReturned.right != null)
next = lastReturned;
m.deleteEntry(lastReturned);
lastReturned = null;
expectedModCount = m.modCount;
}
final void removeDescending() {
if (lastReturned == null)
throw new IllegalStateException();
if (m.modCount != expectedModCount)
throw new ConcurrentModificationException();
m.deleteEntry(lastReturned);
lastReturned = null;
expectedModCount = m.modCount;
}
}
//顺序遍历的子类
final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
SubMapEntryIterator(TreeMap.Entry<K,V> first,
TreeMap.Entry<K,V> fence) {
super(first, fence);
}
public Map.Entry<K,V> next() {
return nextEntry();
}
public void remove() {
removeAscending();
}
}
//倒序遍历的子类
final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
DescendingSubMapEntryIterator(TreeMap.Entry<K,V> last,
TreeMap.Entry<K,V> fence) {
super(last, fence);
}
public Map.Entry<K,V> next() {
return prevEntry();
}
public void remove() {
removeDescending();
}
}
}
/**
* @serial include
*/
static final class AscendingSubMap<K,V> extends NavigableSubMap<K,V> {
private static final long serialVersionUID = 912986545866124060L;
AscendingSubMap(TreeMap<K,V> m,
boolean fromStart, K lo, boolean loInclusive,
boolean toEnd, K hi, boolean hiInclusive) {
super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
}
public Comparator<? super K> comparator() {
return m.comparator();
}
public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
K toKey, boolean toInclusive) {
//对fromKey和toKey做范围判断,即子Map的取值范围必须在原子Map的取值范围内
if (!inRange(fromKey, fromInclusive))
throw new IllegalArgumentException("fromKey out of range");
if (!inRange(toKey, toInclusive))
throw new IllegalArgumentException("toKey out of range");
//因为入参类型是TreeMap,所以此处只能把父Map初始化的TreeMap实例继续传给子Map
return new AscendingSubMap<>(m,
false, fromKey, fromInclusive,
false, toKey, toInclusive);
}
public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
//校验toKey是否在原子Map的取值范围内
if (!inRange(toKey, inclusive))
throw new IllegalArgumentException("toKey out of range");
//注意此处把父Map的fromStart,lo,loInclusive三个参数继续传递到子Map中,即子Map依然在原来的父子Map的取值范围内
return new AscendingSubMap<>(m,
fromStart, lo, loInclusive,
false, toKey, inclusive);
}
public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
if (!inRange(fromKey, inclusive))
throw new IllegalArgumentException("fromKey out of range");
return new AscendingSubMap<>(m,
false, fromKey, inclusive,
toEnd, hi, hiInclusive);
}
public NavigableMap<K,V> descendingMap() {
NavigableMap<K,V> mv = descendingMapView;
return (mv != null) ? mv :
(descendingMapView =
new DescendingSubMap<>(m,
fromStart, lo, loInclusive,
toEnd, hi, hiInclusive));
}
Iterator<K> keyIterator() {
return new SubMapKeyIterator(absLowest(), absHighFence());
}
Spliterator<K> keySpliterator() {
return new SubMapKeyIterator(absLowest(), absHighFence());
}
//注意返回倒序遍历的迭代器时的入参,last即最大值,fence即最小值
Iterator<K> descendingKeyIterator() {
return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
}
final class AscendingEntrySetView extends EntrySetView {
public Iterator<Map.Entry<K,V>> iterator() {
return new SubMapEntryIterator(absLowest(), absHighFence());
}
}
public Set<Map.Entry<K,V>> entrySet() {
EntrySetView es = entrySetView;
return (es != null) ? es : (entrySetView = new AscendingEntrySetView());
}
TreeMap.Entry<K,V> subLowest() { return absLowest(); }
TreeMap.Entry<K,V> subHighest() { return absHighest(); }
TreeMap.Entry<K,V> subCeiling(K key) { return absCeiling(key); }
TreeMap.Entry<K,V> subHigher(K key) { return absHigher(key); }
TreeMap.Entry<K,V> subFloor(K key) { return absFloor(key); }
TreeMap.Entry<K,V> subLower(K key) { return absLower(key); }
}
/**
* @serial include
*/
static final class DescendingSubMap<K,V> extends NavigableSubMap<K,V> {
private static final long serialVersionUID = 912986545866120460L;
DescendingSubMap(TreeMap<K,V> m,
boolean fromStart, K lo, boolean loInclusive,
boolean toEnd, K hi, boolean hiInclusive) {
super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
}
//此处反转comparator主要用于子Map插入元素,正常倒序遍历用不到该comparator
private final Comparator<? super K> reverseComparator =
Collections.reverseOrder(m.comparator);
public Comparator<? super K> comparator() {
return reverseComparator;
}
public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
K toKey, boolean toInclusive) {
if (!inRange(fromKey, fromInclusive))
throw new IllegalArgumentException("fromKey out of range");
if (!inRange(toKey, toInclusive))
throw new IllegalArgumentException("toKey out of range");
return new DescendingSubMap<>(m,
false, toKey, toInclusive,
false, fromKey, fromInclusive);
}
public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
if (!inRange(toKey, inclusive))
throw new IllegalArgumentException("toKey out of range");
return new DescendingSubMap<>(m,
false, toKey, inclusive,
toEnd, hi, hiInclusive);
}
public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
if (!inRange(fromKey, inclusive))
throw new IllegalArgumentException("fromKey out of range");
return new DescendingSubMap<>(m,
fromStart, lo, loInclusive,
false, fromKey, inclusive);
}
public NavigableMap<K,V> descendingMap() {
NavigableMap<K,V> mv = descendingMapView;
return (mv != null) ? mv :
(descendingMapView =
new AscendingSubMap<>(m,
fromStart, lo, loInclusive,
toEnd, hi, hiInclusive));
}
//注意此处的入参
Iterator<K> keyIterator() {
return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
}
Spliterator<K> keySpliterator() {
return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
}
Iterator<K> descendingKeyIterator() {
return new SubMapKeyIterator(absLowest(), absHighFence());
}
final class DescendingEntrySetView extends EntrySetView {
public Iterator<Map.Entry<K,V>> iterator() {
return new DescendingSubMapEntryIterator(absHighest(), absLowFence());
}
}
public Set<Map.Entry<K,V>> entrySet() {
EntrySetView es = entrySetView;
return (es != null) ? es : (entrySetView = new DescendingEntrySetView());
}
TreeMap.Entry<K,V> subLowest() { return absHighest(); }
TreeMap.Entry<K,V> subHighest() { return absLowest(); }
TreeMap.Entry<K,V> subCeiling(K key) { return absFloor(key); }
TreeMap.Entry<K,V> subHigher(K key) { return absLower(key); }
TreeMap.Entry<K,V> subFloor(K key) { return absCeiling(key); }
TreeMap.Entry<K,V> subLower(K key) { return absHigher(key); }
}
8、获取视图方法
同HashMap,视图内部类的实现在迭代器,迭代器的实现与子Map中迭代器的实现基本是一样的。
abstract class PrivateEntryIterator<T> implements Iterator<T> {
//下一个元素
Entry<K,V> next;
//标识当前遍历到的元素
Entry<K,V> lastReturned;
//记录开始遍历时的修改次数
int expectedModCount;
PrivateEntryIterator(Entry<K,V> first) {
expectedModCount = modCount;
lastReturned = null;
next = first;
}
public final boolean hasNext() {
return next != null;
}
//往下遍历
final Entry<K,V> nextEntry() {
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
next = successor(e);
lastReturned = e;
return e;
}
//往前遍历,用于实现倒序遍历
final Entry<K,V> prevEntry() {
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
next = predecessor(e);
lastReturned = e;
return e;
}
public void remove() {
if (lastReturned == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
// 删除时如果该节点的左右节点都存在时,该节点不会被删除而是替换成继承节点的值,该节点就是下一次next()返回的节点,所以此处将next置为该节点
if (lastReturned.left != null && lastReturned.right != null)
next = lastReturned;
deleteEntry(lastReturned);
expectedModCount = modCount;
lastReturned = null;
}
}
final class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
EntryIterator(Entry<K,V> first) {
super(first);
}
public Map.Entry<K,V> next() {
return nextEntry();
}
}
final class ValueIterator extends PrivateEntryIterator<V> {
ValueIterator(Entry<K,V> first) {
super(first);
}
public V next() {
return nextEntry().value;
}
}
final class KeyIterator extends PrivateEntryIterator<K> {
KeyIterator(Entry<K,V> first) {
super(first);
}
public K next() {
return nextEntry().key;
}
}
final class DescendingKeyIterator extends PrivateEntryIterator<K> {
DescendingKeyIterator(Entry<K,V> first) {
super(first);
}
public K next() {
return prevEntry().key;
}
//倒序遍历时跟正序不一样,所以去除了对被删除节点是否左右节点非空的判断
public void remove() {
if (lastReturned == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
deleteEntry(lastReturned);
lastReturned = null;
expectedModCount = modCount;
}
}
9、buildFromSorted方法实现
此方法递归实现的巧妙之处在于充分利用了红黑树每个节点下面最多两个节点的特点,通过对2取整,确保取元素的顺序与构建节点的顺序一致。
/**
* 注意此方法是在TreeMap已经完成comparator和size初始化后才调用的,作为构建红黑树的快捷方法使用
*
* 注意此处的迭代器是已经升序排序的迭代器,如SortedMap或者SortedSet返回的
* 此处的对象流str也是已经升序排序的按照key/value写入的对象流
* 实现策略:根节点是中间元素,通过递归,先构建左子树,然后构建右子树。
* 注意此处构建的红黑树是一个相对简化的红黑树,最底层全部是红色节点,其余的都是黑色节点,且根节点的左右子树元素个数最多查一个
* 此处的lo和hi只是为了保证元素时按照前后顺序从迭代器或者对象流中顺序取出而已,并不是元素真的有索引
*
* @param level 当前树的高度,初始为0
* @param lo 第一个元素的索引,初始为0
* @param hi 最后一个元素的索引,初始为size-1,size为元素个数
* @param redLevel 红色高度,根据size计算而来
*/
@SuppressWarnings("unchecked")
private final Entry<K,V> buildFromSorted(int level, int lo, int hi,
int redLevel,
Iterator<?> it,
java.io.ObjectInputStream str,
V defaultVal)
throws java.io.IOException, ClassNotFoundException {
if (hi < lo) return null;
//取中间值,相当于除以2然后取整
int mid = (lo + hi) >>> 1;
Entry<K,V> left = null;
//第一次lo==mid时,mid=0,该元素是序列中第一个元素,也是最小的一个元素,是红黑树中最左边的左节点
if (lo < mid)
left = buildFromSorted(level+1, lo, mid - 1, redLevel,
it, str, defaultVal);
K key;
V value;
//从迭代器或者对象流中读取key/value
if (it != null) {
if (defaultVal==null) {
Map.Entry<?,?> entry = (Map.Entry<?,?>)it.next();
key = (K)entry.getKey();
value = (V)entry.getValue();
} else {
key = (K)it.next();
value = defaultVal;
}
} else { // use stream
key = (K) str.readObject();
value = (defaultVal != null ? defaultVal : (V) str.readObject());
}
Entry<K,V> middle = new Entry<>(key, value, null);
// 最下面一层的节点为红色,level会随着递归不断增加,对红黑树而言,左子树跟右子树的高度
if (level == redLevel)
middle.color = RED;
//构建左子树
if (left != null) {
middle.left = left;
left.parent = middle;
}
//构建右子树,第一次执行时mid=1,hi=2
if (mid < hi) {
Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
it, str, defaultVal);
middle.right = right;
right.parent = middle;
}
return middle;
}
private static int computeRedLevel(int sz) {
int level = 0;
for (int m = sz - 1; m >= 0; m = m / 2 - 1)
level++;
return level;
}