1.问题
我们在内存中处理排序时,虽说有了stream流,好多了,但是总是拖好长一堆尾巴,感觉不太优雅,null as last也需要单独处理,现在有了hutool中的工具类,这个问题就有了更好的解决方案。
2.案例
List<User> userList = new ArrayList<>();
userList.add(new User(1L, "张三", 25));
userList.add(new User(2L, "李四", 20));
userList.add(new User(3L, "王五", 30));
userList.add(new User(4L, "赵六", null));
// 1. 按 age 升序(空值默认排最后,无需手动判断)
CollUtil.sort(userList, ComparatorUtil.comparing(User::getAge));
System.out.println("age 升序(空值最后):" + userList);
// 2. 按 age 降序(一键反转,无需 reversed())
CollUtil.sort(userList, ComparatorUtil.reverse(ComparatorUtil.comparing(User::getAge)));
System.out.println("age 降序(空值最后):" + userList);
// 3. 空值排最前
CollUtil.sort(userList, ComparatorUtil.nullsFirst(ComparatorUtil.comparing(User::getAge)));
System.out.println("age 升序(空值最前):" + userList);
List<User> userList = new ArrayList<>();
userList.add(new User("张三", 25));
userList.add(new User("李四", 20));
userList.add(new User("王五", 25));
userList.add(new User("赵六", 20));
userList.add(new User(null, 25)); // 空值测试
// 1. 生成字段比较器(空值安全)
Comparator<User> ageComp = ComparatorUtil.comparing(User::getAge); // age 升序
Comparator<User> nameDescComp = ComparatorUtil.reverse(ComparatorUtil.comparing(User::getName)); // name 降序
// 2. 多字段级联排序(先 age 升序,再 name 降序)
CollUtil.sort(userList, ComparatorUtil.thenComparing(ageComp, nameDescComp));
System.out.println("多字段排序(空值安全):" + userList);
// 输出:[赵六(20), 李四(20), null(25), 王五(25), 张三(25)]
List<User> userList = new ArrayList<>();
userList.add(new User("张三", new Date(900000000000L)));
userList.add(new User("李四", null));
userList.add(new User("王五", new Date(800000000000L)));
// 1. 空值排最后(默认)
CollUtil.sort(userList, ComparatorUtil.comparing(User::getBirthday));
System.out.println("空值排最后:" + userList);
// 2. 空值排最前
CollUtil.sort(userList, ComparatorUtil.nullsFirst(ComparatorUtil.comparing(User::getBirthday)));
System.out.println("空值排最前:" + userList);
// 3. 空值排最后 + 降序
CollUtil.sort(userList, ComparatorUtil.reverse(ComparatorUtil.nullsLast(ComparatorUtil.comparing(User::getBirthday))));
System.out.println("空值最后+降序:" + userList);
// 复用:按字符串长度排序的自定义比较器,定义成静态全局常量
private static final Comparator<String> STR_LENGTH_COMP = Comparator.comparingInt(String::length);
List<User> userList = new ArrayList<>();
userList.add(new User("张三"));
userList.add(new User("李四四"));
userList.add(new User("王五"));
userList.add(new User("赵六六六"));
userList.add(new User(null)); // 空值测试
// 1. 按姓名长度升序(空值安全)
Comparator<User> nameLenComp = ComparatorUtil.comparing(User::getName, STR_LENGTH_COMP);
// 2. 长度相同按姓名降序
Comparator<User> nameDescComp = ComparatorUtil.reverse(ComparatorUtil.comparing(User::getName));
// 3. 级联排序
CollUtil.sort(userList, ComparatorUtil.thenComparing(nameLenComp, nameDescComp));
System.out.println("自定义长度排序(空值安全):" + userList);
// 输出:[张三, 王五, 李四四, 赵六六六, null]
// 扩展:按数字绝对值排序
List<Integer> amountList = CollUtil.newArrayList(5, -3, 8, -10);
CollUtil.sort(amountList, ComparatorUtil.comparing(Math::abs));
System.out.println("按绝对值升序:" + amountList); // [0, -3, 5, 8, -10]
// 1. 可变列表升序(默认)
List<Integer> numList = CollUtil.newArrayList(3, 1, 2);
CollUtil.sort(numList);
System.out.println("数字升序:" + numList); // [1,2,3]
// 2. 不可变列表排序(自动转可变,返回新列表)
List<String> strList = List.of("b", "a", "c");
List<String> sortedStrList = CollUtil.sort(strList);
System.out.println("字符串升序:" + sortedStrList); // [a,b,c]
// 3. 自定义排序(按字符串长度降序)
List<String> strLenList = CollUtil.newArrayList("apple", "banana", "pear");
CollUtil.sort(strLenList, ComparatorUtil.reverse(ComparatorUtil.comparing(String::length)));
System.out.println("字符串长度降序:" + strLenList); // [banana, apple, pear]
6079

被折叠的 条评论
为什么被折叠?



