小结
SortedMap在遍历时严格按照Key的顺序遍历,最常用的实现类是TreeMap;
作为SortedMap的Key必须实现Comparable接口,或者传入Comparator;
要严格按照compare()规范实现比较逻辑,否则,TreeMap将不能正常工作。
HashMap是一种以空间换时间的映射表,它的实现原理决定了内部的Key是无序的,即遍历HashMap的Key时,其顺序是不可预测的(但每个Key都会遍历一次且仅遍历一次)。
还有一种Map,它在内部会对Key进行排序,这种Map就是SortedMap。注意到SortedMap是接口,它的实现类是TreeMap。
int 等基本类型不能用comparable接口,需要用包装类型
使用TreeMap时,放入的Key必须实现Comparable接口。String、Integer这些类已经实现了Comparable接口,因此可以直接作为Key使用。作为Value的对象则没有任何要求。
如果作为Key的class没有实现Comparable接口,那么,必须在创建TreeMap时同时指定一个自定义排序算法:
public class Main {public static void main(String[] args) {Map<Person, Integer> map = new TreeMap<>(new Comparator<Person>() {@Overridepublic int compare(Person p1, Person p2) {return p1.name.compareTo(p2.name);}});map.put(new Person("Tom"), 1);map.put(new Person("Bob"), 2);map.put(new Person("Lily"), 3);for (Person key : map.keySet()) {System.out.println(key);}// {Person: Bob}, {Person: Lily}, {Person: Tom}System.out.println(map.get(new Person("Bob"))); // 2}}class Person {public String name;Person(String name) {this.name = name;}public String toString() {return "{Person: " + name + "}";}}
注意到Comparator接口要求实现一个比较方法,它负责比较传入的两个元素a和b,如果ab,则返回正数,通常是1。TreeMap内部根据比较结果对Key进行排序。
从上述代码执行结果可知,打印的Key确实是按照Comparator定义的顺序排序的。如果要根据Key查找Value,我们可以传入一个new Person(“Bob”)作为Key,它会返回对应的Integer值2。
另外,注意到Person类并未覆写equals()和hashCode(),因为TreeMap不使用equals()和hashCode()
如果作为Key的class没有实现Comparable接口,那么,必须在创建TreeMap时同时指定一个自定义排序算法:
public class MM {public static void main(String[] args) {Map<Student, Integer> map = new TreeMap<>(new Comparator<Student>() {public int compare(Student p1, Student p2) {return p1.score > p2.score ? -1 : 1;// return p1.score.compareTo(p2.score);}});map.put(new Student("Tom", 77), 1);map.put(new Student("Bob", 66), 2);map.put(new Student("Lily", 99), 3);for (Student key : map.keySet()) {System.out.println(key);}System.out.println(map.get(new Student("Bob", 66))); // null? 把上面代码改成注掉的就可以}}class Student {public String name;public Integer score;Student(String name, Integer score) {this.name = name;this.score = score;}public String toString() {return String.format("{%s: score=%d}", name, score); //format使用指定的格式字符串和参数返回格式化字符串}}{Lily: score=99}{Tom: score=77}{Bob: score=66}null
解决15行的小问题
