gpt4 book ai didi

java - 如何使用 Java8 流从嵌套对象组装 Map

转载 作者:行者123 更新时间:2023-12-02 12:27:46 25 4
gpt4 key购买 nike

假设我有 3 辆车,每辆车有 3 个发动机,每个发动机有 3 个零件。我怎样才能创建一个map of <engine_model, List<parts>>使用 Java8 流摆脱这个?

在常规java中我会执行以下操作:

Map<String, List<Parts>> map = new HashMap<String, List<Parts>>();
for (Car car: cars){
for (Engine engine: car.getEngines()){
if (!map.contains(engine.getModel())){
map.put(engine.getModel(), new ArrayList<Part>());
}
for (Part part: engine.getParts()){
map.get(engine.getModel()).add(part);
}
}
}

这里mapmap它将发动机的型号 ( type String ) 映射到与该型号相关的所有零件的列表。不同的汽车可以有相同的发动机型号。

我尝试执行以下操作:

carList.stream().flatMap(p -> p.getEngines().stream())
.collect(Collectors.groupingBy(p -> p.getModel(),
Collectors.mapping(Engine::getParts, Collectors.toList())))

问题是使用上面我得到 Map<String, List<List<Part>>>而且我要 Map<String, List<Part>>

我想一个等效的问题是:如何更改 List of Lists到只是List在上面的例子中?

最佳答案

首先,您甚至可以简化命令式变体:

Map<String, List<Part>> map = new HashMap<>();
for(Car car: cars) {
for(Engine engine: car.getEngines()) {
map.computeIfAbsent(engine.getModel(), key -> new ArrayList<>())
.addAll(engine.getParts());
}
}

在决定功能变体是否真的是一种改进时,这一点很重要。 flatMap + groupingBy 收集器是正确的方法,但事实上您有一个(Part)列表需要展平,这是一个额外的障碍。在 Java 9 中,您可以编写

Map<String, List<Part>> map = cars.stream()
.flatMap(car -> car.getEngines().stream())
.collect(Collectors.groupingBy(Engine::getModel,
Collectors.flatMapping(e -> e.getParts().stream(), Collectors.toList())));

但在那之前,我们必须手动组装一个等效的收集器:

Map<String, List<Part>> map = cars.stream()
.flatMap(car -> car.getEngines().stream())
.collect(Collectors.groupingBy(Engine::getModel,
Collector.of(ArrayList::new, (l,e) -> l.addAll(e.getParts()),
(l1,l2) -> { l1.addAll(l2); return l1; })));

所以我现在会考虑继续循环。

关于java - 如何使用 Java8 流从嵌套对象组装 Map<Key, Value>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37999452/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com