TreeMap自定义排序

我们都知道TreeMap可以根据key按字典升序排序。但在某些场景下,我们需要自定义排序规则,为了代码优雅一些,我们也希望在stream中groupingBy时自定义排序规则,就可以参考本文的实现。

1. 使用TreeMap默认的排序规则(按字典升序排序)

先来看一下默认的排序规则。

java 复制代码
/**
 * 使用TreeMap默认的排序规则(按字典升序排序)
 */
private static void sortByDefault() {
    TreeMap<String, Integer> treeMap = new TreeMap<>();
    for (int index = 0; index < 5; index++) {
        treeMap.put("str_" + index, index);
    }
    System.out.println("*****TreeMap默认排序规则*****");
    treeMap.forEach((k, v) -> System.out.println(k + " : " + v));
    System.out.println();
}

2. 使用自定义排序规则

使用自定义排序规则对TreeMap进行实例化。

java 复制代码
/**
 * 使用自定义排序规则
 */
private static void sortByCustom() {
    Comparator<String> comparator = (String s1, String s2) -> SortEnum.getSortWeightByValue(s1) - SortEnum.getSortWeightByValue(s2);
    TreeMap<String, Integer> treeMap = new TreeMap<>(comparator);
    for (int index = 0; index < 5; index++) {
        treeMap.put("str_" + index, index);
    }
    System.out.println("*****TreeMap自定义排序规则*****");
    treeMap.forEach((k, v) -> System.out.println(k + " : " + v));
    System.out.println();
}

3. GroupingBy时使用自定义排序规则

一开始直接用TreeMap::new作为groupingBy方法的第二个参数,但是这种办法只能引用TreeMap的无参构造方法。查看groupingBy的入参可以发现,第二个参数是Supplier类型,于是手动实现Supplier,在方法体中传入自定义比较器,然后返回TreeMap对象。

java 复制代码
/**
 * GroupingBy时使用自定义排序规则
 */
private static void sortWhenGroupingBy() {
    List<String> list = new ArrayList<>();
    for (int index = 0; index < 5; index++) {
        list.add("str_" + index);
    }
    Comparator<String> comparator = (s1, s2) -> SortEnum.getSortWeightByValue(s1) - SortEnum.getSortWeightByValue(s2);
    // 如果现在外面定义好Supplier,需要声明TreeMap的key和value的类型,否则可能出现类型不兼容的异常
    // Supplier<TreeMap<String, List<String>>> supplier = () -> new TreeMap<>(comparator);
    // TreeMap<String, List<String>> treeMap = list.stream().collect(Collectors.groupingBy(Function.identity(), supplier, Collectors.toList()));
    TreeMap<String, List<String>> treeMap = list.stream().collect(Collectors.groupingBy(Function.identity(), () -> new TreeMap<>(comparator), Collectors.toList()));
    System.out.println("*****GroupingBy时自定义排序规则*****");
    treeMap.forEach((k, v) -> System.out.println(k + " : " + v));
    System.out.println();
}

完整代码

自定义排序权重类

java 复制代码
public enum SortEnum {
    ZERO(0, "str_1"),
    FIRST(1, "str_0"),
    SECOND(2, "str_3"),
    THREE(3, "str_2"),
    ;
    private int sortWeight;
    private String value;

    SortEnum(int sortWeight, String value) {
        this.sortWeight = sortWeight;
        this.value = value;
    }

    public static int getSortWeightByValue(String value) {
        for (SortEnum sortEnum : SortEnum.values()) {
            if (sortEnum.value.equals(value)) {
                return sortEnum.sortWeight;
            }
        }
        return Integer.MAX_VALUE;
    }
}

测试代码

java 复制代码
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.stream.Collectors;

public class TestTreeMap {
    public static void main(String[] args) {
        sortByDefault();
        sortByCustom();
        sortWhenGroupingBy();
    }

    /**
     * 使用TreeMap默认的排序规则(按字典升序排序)
     */
    private static void sortByDefault() {
        TreeMap<String, Integer> treeMap = new TreeMap<>();
        for (int index = 0; index < 5; index++) {
            treeMap.put("str_" + index, index);
        }
        System.out.println("*****TreeMap默认排序规则*****");
        treeMap.forEach((k, v) -> System.out.println(k + " : " + v));
        System.out.println();
    }

    /**
     * 使用自定义排序规则
     */
    private static void sortByCustom() {
        Comparator<String> comparator = (String s1, String s2) -> SortEnum.getSortWeightByValue(s1) - SortEnum.getSortWeightByValue(s2);
        TreeMap<String, Integer> treeMap = new TreeMap<>(comparator);
        for (int index = 0; index < 5; index++) {
            treeMap.put("str_" + index, index);
        }
        System.out.println("*****TreeMap自定义排序规则*****");
        treeMap.forEach((k, v) -> System.out.println(k + " : " + v));
        System.out.println();
    }

    /**
     * GroupingBy时使用自定义排序规则
     */
    private static void sortWhenGroupingBy() {
        List<String> list = new ArrayList<>();
        for (int index = 0; index < 5; index++) {
            list.add("str_" + index);
        }
        Comparator<String> comparator = (s1, s2) -> SortEnum.getSortWeightByValue(s1) - SortEnum.getSortWeightByValue(s2);
        // 如果现在外面定义好Supplier,需要声明TreeMap的key和value的类型,否则可能出现类型不兼容的异常
        // Supplier<TreeMap<String, List<String>>> supplier = () -> new TreeMap<>(comparator);
        // TreeMap<String, List<String>> treeMap = list.stream().collect(Collectors.groupingBy(Function.identity(), supplier, Collectors.toList()));
        TreeMap<String, List<String>> treeMap = list.stream().collect(Collectors.groupingBy(Function.identity(), () -> new TreeMap<>(comparator), Collectors.toList()));
        System.out.println("*****GroupingBy时自定义排序规则*****");
        treeMap.forEach((k, v) -> System.out.println(k + " : " + v));
        System.out.println();
    }
}

运行结果:

复制代码
*****TreeMap默认排序规则*****
str_0 : 0
str_1 : 1
str_2 : 2
str_3 : 3
str_4 : 4

*****TreeMap自定义排序规则*****
str_1 : 1
str_0 : 0
str_3 : 3
str_2 : 2
str_4 : 4

*****GroupingBy时自定义排序规则*****
str_1 : [str_1]
str_0 : [str_0]
str_3 : [str_3]
str_2 : [str_2]
str_4 : [str_4]
相关推荐
lhldsg2 小时前
全民健身解决方案小程序开发:从0到1的技术实战
java·数据库·需求分析
jason成都2 小时前
Spring WebFlux 适配达梦新方案|dm‑r2dbc:Netty 异步传输的实验性 R2DBC 驱动
java·后端·spring
泡海椒3 小时前
内置SPI函数库详解:JQuick-Java Builtin工具类实战用法
java·开发语言·python
辰烨chenye3 小时前
LeetCode Hot 100 题解 · 二分篇
java·算法·leetcode
小羊没烦恼!3 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
小荷才露尖尖角,早有蜻蜓立上头4 小时前
过滤器的4种创建方式
java
大圣编蚕5 小时前
Java ByteArrayInputStream 详解:从入门到实战
java·开发语言·算法
程序员阿明5 小时前
idea把插件啥的不默认放在C盘
java·ide·intellij-idea
linweidong6 小时前
中科闻歌Java面试题及参考答案
java·python·大模型·提示词·ai agent·mcp·rag原理
OpenAnolis小助手6 小时前
一句话看透 JVM,SysOM 诊断 Skill 新增 Java 应用诊断能力
java·开发语言·jvm·阿里云·操作系统控制台·sysom