1. 根据 key
排序
引言
TreeMap
中key 可以自动对 String 类型或8大基本类型的包装类型进行排序。- 但是,
TreeMap
无法直接对自定义类型进行排序。- 当我们想对对
TreeMap
中key
中的自定义类型排序时,必须要指定**排序规则。主要有两种解决方案**:
根据 key
排序,主要有两种方法
- 方法1:实现
Comparator
接口,并传递给TreeMap
构造器; - 方法2:使得
key
对应类implements Comparable
接口。
两种排序规则如何选择呢?
- 当比较规则不会发生改变的时候,或者说比较规则只有一个的时候,建议实现
Comparable
接口; - 当比较规有多个,并且需要在多个比较规则之间频繁切换时,建议使用
Comparator
比较器。
方法1:实现 Comparator
接口
import java.util.*;
class Solution {
public static void main(String[] args) {
Map<Person, String> map = new TreeMap<>((person1, person2) -> {
// 先按照age降序排序
if (person1.getAge() - person2.getAge() != 0) {
return person2.getAge() - person1.getAge();
}
// age相同时,按照name升序排序
return person1.getName().compareTo(person2.getName());
});
map.put(new Person("zhangsan", 15), "001");
map.put(new Person("lisi", 18), "002");
map.put(new Person("wangwu", 20), "003");
map.put(new Person("zhaoliu", 18), "004");
map.put(new Person("ouyangfeng", 60), "006");
map.put(new Person("hongqigong", 60), "005");
System.out.println("排序后,map = ");
for (Map.Entry<Person, String> entry : map.entrySet()) {
System.out.println(entry);
}
}
}
class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name = " + name +
", age = " + age +
'}';
}
}
运行结果如下:
方法2:implements Comparable
import java.util.*;
class Solution {
public static void main(String[] args) {
Map<Person, String> map = new TreeMap<>();
map.put(new Person("zhangsan", 15), "001");
map.put(new Person("lisi", 18), "002");
map.put(new Person("wangwu", 20), "003");
map.put(new Person("zhaoliu", 18), "004");
map.put(new Person("ouyangfeng", 60), "006");
map.put(new Person("hongqigong", 60), "005");
System.out.println("排序后,map = ");
for (Map.Entry<Person, String> entry : map.entrySet()) {
System.out.println(entry);
}
}
}
//
class Person implements Comparable<Person> {
private String name;
private int age;
@Override
public int compareTo(Person person) {
// 先按照age降序排序
if (this.getAge() - person.getAge() != 0) {
return person.getAge() - this.getAge();
}
// age相同时,按照name升序排序
return this.getName().compareTo(person.getName());
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name = " + name +
", age = " + age +
'}';
}
}
2. 根据 value
排序
同上根据
key
排序,根据value
排序时,也可以有两种方法,这里仅仅展示“实现Comparator
接口”的方法
map
根据 value
排序时,和根据 key
排序相比 较为繁琐,具体步骤如下:
- 将
map.entrySet()
转存至list
中,即lsit
中每个元素的类型为Map.Entry
; - 利用
Collections.sort
根据list
中ertry.getValue()
进行排序; - “实现
Comparator
接口”,自定义ertry.getValue()
的排序规则。
import java.util.*;
class Solution {
public static void main(String[] args) {
Map<String, Person> map = new HashMap<>();
map.put("001", new Person("zhangsan", 15));
map.put("002", new Person("lisi", 18));
map.put("003", new Person("wangwu", 20));
map.put("004", new Person("zhaoliu", 18));
map.put("006", new Person("ouyangfeng", 60));
map.put("005", new Person("hongqigong", 60));
System.out.println("排序前,map = " );
for (Map.Entry<String, Person> entry : map.entrySet()) {
System.out.println(entry);
}
// 1、map to list
List<Map.Entry<String, Person>> entries = new ArrayList<>(map.entrySet());
// 2、重写排序规则
Collections.sort(entries, (entry1, entry2) -> {
Person person1 = entry1.getValue();
Person person2 = entry2.getValue();
// 先按照age降序排序
if (person1.getAge() - person2.getAge() != 0) {
return person2.getAge() - person1.getAge();
}
// age相同时,按照name升序排序
return person1.getName().compareTo(person2.getName());
});
System.out.println("\n排序后,entries = ");
for (Map.Entry<String, Person> entry : entries) {
System.out.println(entry);
}
}
}
class Person {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name = " + name +
", age = " + age +
'}';
}
}
运行结果如下: