TreeMap排序
TreeMap按照Key排序
TreeMap底层是根据红黑树的数据结构来构建的,默认是根据Key的自然排序来组织(比如Ingeger的大小,String的字典排序).所以,TreeMap只能只能按照key来排序,是不能根据Value来排序的.
key为基本包装类
当key属于基本包装类时(Integer,String等),它们都已经实现了Comparable接口,所以允许不重写compareTo()
或者compare()
方法.
public void defaultByKey() {
Map<Integer, Character> map = new TreeMap<>();
map.put(5, 'a');
map.put(2, 'b');
map.put(3, 'c');
map.put(1, 'd');
map.put(4, 'e');
System.out.println(map);
Map<String, Character> map2 = new TreeMap<>();
map2.put("zzz", 'a');
map2.put("ddd", 'b');
map2.put("aaa", 'c');
map2.put("ccc", 'd');
map2.put("bbb", 'e');
System.out.println(map2);
}
运行结果为:
{1=d, 2=b, 3=c, 4=e, 5=a}
{aaa=c, bbb=e, ccc=d, ddd=b, zzz=a}
key为自定义包装类
不实现自然排序或者定制排序
当key为自定义类时候,必须重写compareTo()
或者compare()
方法,否则报错.
class Person {
int age;
public Person(int age) {
this.age = age;
}
}
public void comparableDemo() {
Map<Person, String> map = new TreeMap<>();
map.put(new Person(5), "wang");
System.out.println(map);
}
运行结果为:
java.lang.ClassCastException: map.TreeMapDemo$Person cannot be cast to java.lang.Comparable
实现自然排序
自然排序即让被排序的类实现Comparable接口,然后重写compareTo方法.
class Person implements Comparable<Person> {
int age;
public Person(int age) {
this.age = age;
}
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
/**
* 自然排序
*/
@Test
public void comparableDemo() {
Map<Person, String> map = new TreeMap<>();
map.put(new Person(5), "wang");
map.put(new Person(2), "zhang");
map.put(new Person(3), "liu");
System.out.println(map);
}
运行结果为:
{Person{age=2}=zhang, Person{age=3}=liu, Person{age=5}=wang}
实现定制排序
定制排序即创建一个新的类并且实现Comparator接口,重写compare方法.创建TreeMap的时候,传入比较器.
class PersonD {
int age;
public PersonD(int age) {
this.age = age;
}
@Override
public String toString() {
return "PersonD{" +
"age=" + age +
'}';
}
}
@Test
public void comparatorDemo() {
Map<PersonD, String> map = new TreeMap<>(new Comparator<PersonD>() {
@Override
public int compare(PersonD o1, PersonD o2) {
return o1.age - o2.age;
}
});
map.put(new PersonD(5), "wang");
map.put(new PersonD(2), "zhang");
map.put(new PersonD(3), "liu");
System.out.println(map);
}
按照Value排序
思路:将TreeMap的EntrySet转换成list(放入list中),然后使用Collections.sort排序.
/**
* TreeMap按照value来排序
*/
public void sortByValue() {
Map<Character, Integer> map = new TreeMap<>();
map.put('q', 8);
map.put('b', 8);
map.put('a', 10);
map.put('c', 3);
map.put('d', 4);
System.out.println("默认以Key排序: ");
System.out.println(map);
System.out.println("................................");
List<Map.Entry<Character, Integer>> list = new ArrayList<>(map.entrySet());
System.out.println("将entrySet放入list中: ");
System.out.println(list);
System.out.println("................................");
// 匿名内部类方式重写compare方法
// Collections.sort(list, new Comparator<Map.Entry<Character, Integer>>() {
// @Override
// public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
// return o1.getValue().compareTo(o2.getValue());
// }
// });
// lambda表达式重写compare方法
Collections.sort(list, (o1, o2) -> {
return o1.getValue().compareTo(o2.getValue());
});
System.out.println("按照value值排序后: ");
System.out.println(list);
}
运行结果为:
默认以Key排序:
{a=10, b=8, c=3, d=4, q=8}
................................
将entrySet放入list中:
[a=10, b=8, c=3, d=4, q=8]
................................
按照value值排序后:
[c=3, d=4, b=8, q=8, a=10]