AbstractMap.SimpleEntry 解决了我要一次性构造Map的需求

  1. 最简单的场景, 我有这么个对象集合, 为了代码简洁, 示例均不考虑key冲突场景.
java 复制代码
@Data
public class TestModel {
    private Long id;
    private BigDecimal taxRate;
}

我要是想构造一个id为key, taxRate为value的Map, 就很简单, 像这样.

java 复制代码
var testModel = new ArrayList<TestModel>();
var idValueMap = testModel.stream()
    .collect(Collectors.toMap(TestModel::getId, TestModel::getTaxRate));

  1. 突然数据结构变了, id变成了列表.
java 复制代码
@Data
public class TestModel {
    private BigDecimal taxRate;
    private List<Long> ids;
}

我要是想构造的Map以ids中的每一个id为key, 怎么搞呢, 上代码.

less 复制代码
public static void main(String[] args) {
    var testModels = List.of(new TestModel(BigDecimal.ONE, List.of(1L, 2L, 3L)),
                             new TestModel(BigDecimal.TEN, List.of(4L, 5L, 6L)));

    Map<Long, BigDecimal> idValueMap = testModels.stream()
        .flatMap(tm -> tm.getIds().stream()
            .map(id -> new AbstractMap.SimpleEntry<>(id, tm.getTaxRate()) {
            }))
        .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
    System.out.println(idValueMap);
}

输出结果如图:

  1. 突然数据结构又变了, 像这样
less 复制代码
@Data
@AllArgsConstructor
public class TestModel {
    private BigDecimal taxRate;
    private List<Long> ids;
    private List<Long> orderIds;
}

我要构造一个Map嵌套的结构, 是这样Map<ids.id, Map<orderIds.id, value>> , 怎么搞呢, 上代码

java 复制代码
public static void main(String[] args) {
    var testModels = List.of(new TestModel(BigDecimal.ONE, List.of(1L, 2L, 3L), List.of(7L, 8L, 9L)),
                             new TestModel(BigDecimal.TEN, List.of(4L, 5L, 6L), List.of(17L, 18L, 19L)));

    Map<Long, Map<Long, BigDecimal>> result = testModels.stream()
        .flatMap(tm -> tm.getIds().stream()
            .map(id -> new AbstractMap.SimpleEntry<>(id, tm.orderIds.stream()
                .map(oId -> new AbstractMap.SimpleEntry<>(oId, tm.getTaxRate()))
                .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue))
            ) {
            }))
        .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
    System.out.println(result);
}

输出结果如图:

  1. 假如数据结构又变了, 像这样
swift 复制代码
@Data
@AllArgsConstructor
public class TestModel {
    private List<Long> ids;
    private List<Long> orderIds;
    private List<TypeValue> typeValues;

    @Data
    static class TypeValue {
        private List<String> type;
        private String value;
    }
}

我还是想构造一个Map, 结构呢是这样Map<id, Map<orderId, Map<type, value>>>, 如果不允许定义额外的局部变量, 怎么写? 上代码

看答案之前, 先试试自己的java基本功扎实不扎实.

java 复制代码
public static void main(String[] args) throws JsonProcessingException {
    var testModels = List.of(new TestModel(List.of(1L, 2L, 3L),
                                           List.of(7L, 8L, 9L),
                                           List.of(new TypeValue(List.of("a", "b", "c"), 1))),
                             new TestModel(List.of(4L, 5L, 6L),
                                           List.of(17L, 18L, 19L),
                                           List.of(new TypeValue(List.of("d", "e", "f"), 2))));

    Map<Long, Map<Long, Map<String, Integer>>> result = testModels.stream().flatMap(tm -> tm.getIds().stream().map(
        id -> new AbstractMap.SimpleEntry<>(id,
                                            tm.orderIds.stream().map(oId -> new AbstractMap.SimpleEntry<>(oId,
                                                                                                          tm.getTypeValues().stream().flatMap(
                                                                                                              tv -> tv.getType().stream().map(
                                                                                                                  t -> new AbstractMap.SimpleEntry<>(
                                                                                                                      t,
                                                                                                                      tv.getValue()))).collect(
                                                                                                              Collectors.toMap(
                                                                                                                  AbstractMap.SimpleEntry::getKey,
                                                                                                                  AbstractMap.SimpleEntry::getValue)))).collect(
                                                Collectors.toMap(AbstractMap.SimpleEntry::getKey,
                                                                 AbstractMap.SimpleEntry::getValue))) {
        })).collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
    ObjectMapper objectMapper = new ObjectMapper();
    System.out.println(objectMapper.writeValueAsString(result));
}

输出结果如下: 格式化后太长了, 我就不格式化了

json 复制代码
{"1":{"7":{"a":1,"b":1,"c":1},"8":{"a":1,"b":1,"c":1},"9":{"a":1,"b":1,"c":1}},"2":{"7":{"a":1,"b":1,"c":1},"8":{"a":1,"b":1,"c":1},"9":{"a":1,"b":1,"c":1}},"3":{"7":{"a":1,"b":1,"c":1},"8":{"a":1,"b":1,"c":1},"9":{"a":1,"b":1,"c":1}},"4":{"17":{"d":2,"e":2,"f":2},"18":{"d":2,"e":2,"f":2},"19":{"d":2,"e":2,"f":2}},"5":{"17":{"d":2,"e":2,"f":2},"18":{"d":2,"e":2,"f":2},"19":{"d":2,"e":2,"f":2}},"6":{"17":{"d":2,"e":2,"f":2},"18":{"d":2,"e":2,"f":2},"19":{"d":2,"e":2,"f":2}}}

实际的业务场景是公司的财务系统中, 会从各种层级维度来设置税率相关的信息, 在查找税率时会产生类似示例代码的场景.

相关推荐
赤壁小虾12 分钟前
【渲染流水线】[逐片元阶段]-[透明度测试]以UnityURP为例
java·前端·数据库
Zane19941 小时前
@property 到底是怎么把方法伪装成属性的?一文吃透 property、staticmethod、classmethod
后端·python
青山木1 小时前
Hot 100 --- 搜索插入位置
java·数据结构·算法·leetcode
Jul1en_1 小时前
【Claude Code Compact】源码级别的学习上下文压缩
java·前端·学习·github·ai编程
XWalnut2 小时前
SpringBoot快速入门
java·spring boot·后端
前端 贾公子2 小时前
第06章:结构化输出 (上)
java·服务器·前端
念何架构之路2 小时前
restartmanager-重启管理子系统
java·开发语言
用户8181870627462 小时前
第21章 JDBC 异常全集与连接池诊断
后端
Java内核笔记2 小时前
告别第三方库!Spring Boot 4 原生 API 版本控制全解析:4 种策略 + 实战案例
java·后端
神奇小汤圆2 小时前
把Spring Boot 4的Native Image玩明白了,启动3秒变50毫秒的踩坑全记录
后端