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}}}

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

相关推荐
rzl029 分钟前
java web5(黑马)
java·开发语言·前端
君爱学习15 分钟前
RocketMQ延迟消息是如何实现的?
后端
guojl29 分钟前
深度解读jdk8 HashMap设计与源码
java
Falling4232 分钟前
使用 CNB 构建并部署maven项目
后端
guojl34 分钟前
深度解读jdk8 ConcurrentHashMap设计与源码
java
程序员小假43 分钟前
我们来讲一讲 ConcurrentHashMap
后端
爱上语文1 小时前
Redis基础(5):Redis的Java客户端
java·开发语言·数据库·redis·后端
A~taoker1 小时前
taoker的项目维护(ng服务器)
java·开发语言
萧曵 丶1 小时前
Rust 中的返回类型
开发语言·后端·rust