一、类继承图
二、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) {
Compar