Java8比较器Comparator的多条件排序用法

0
字数 255
阅读时间 1 分钟

在项目中经常遇到需要多字段排序的情况,比如某班级同学成绩按照总分降序排列,总分同分的按照姓名字母表顺序升序排列,其实现方式如下:

实体集合排序

先创建一个学生实体类:

@Data
public class User {

private Integer score;
private String name;
}

再在测试类里面构建一个学生集合:

//这是匿名内部类初始化方式,不懂得回去学java基础,没搞错 《30天精通Java》 之类的垃圾骗钱书的前几页就有
private static final List<User> userList = new ArrayList<User>() {{
add(new User(1, "Az"));
add(new User(1, "Aa"));
add(new User(3, "Bb"));
add(new User(1, "Ab"));
}};

再创建一个 main 方法:

public static void main(String[] args) {
//排序器,采用函数式构建排序器的前提是字段类型已经正确实现了Comparable接口
Comparator<User> userComparator = Comparator
//第一个字段升序排列
.comparing(User::getScore)
//将上面的排序方式反转为降序排序
.reversed()
//第二个字段排升序排列
.thenComparing(User::getName);
//排序
userList.sort(userComparator);
System.out.println(userList);
}

并执行,得到结果:

[User{id=3, name='Bb'}, User{id=1, name='Aa'}, User{id=1, name='Ab'}, User{id=1, name='Az'}]

可见排序结果是正确的。

Map 集合排序

有些时候可能需要排序 Map 集合(List<Map<String,Object>>),字段和排序规则和像上面一样:

先在测试类里面构建一个学生 Map 集合:

private static final List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>() {{
add(new HashMap<String, Object>() {{
put("score", 1);
put("name", "Az");
}});
add(new HashMap<String, Object>() {{
put("score", 1);
put("name", "A2");
}});
add(new HashMap<String, Object>() {{
put("score", 3);
put("name", "Bb");
}});
add(new HashMap<String, Object>() {{
put("score", 1);
put("name", "Ab");
}});
}};

再创建一个 main 方法:

public static void main(String[] args) {
Comparator<Map<String, Object>> userComparator = Comparator
//注意多字段排序时,这里的 (Map<String, Object> map)-> 不能省略为 map->,会导致编译器无法自动类型判断而报错
.comparing((Map<String, Object> map) -> (Integer) map.get("score")).reversed()
.thenComparing((Map<String, Object> map) -> (String) map.get("name"));

mapList.sort(userComparator);
System.out.println(mapList);
}

并执行,得到结果:

[User{id=3, name='Bb'}, User{id=1, name='Aa'}, User{id=1, name='Ab'}, User{id=1, name='Az'}]

可见排序结果是正确的。


使用 Adobe Typekit 给博客换思源系列字体 基于Github Actions实现Hexo博客自动切换主题