gpt4 book ai didi

java - 使用流对深层嵌套列表进行分组和求和

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:54:05 25 4
gpt4 key购买 nike

我有三个类(class):

public class Supply {
private final List<Compartment> compartments;

public List<Compartment> getCompartments() {
return compartments;
}

public Supply(List<Compartment> compartments) {
this.compartments = compartments;
}
}

public class Compartment {
private final String itemId;
private final List<Unit> units;

public String getItemId() {
return itemId;
}

public List<Unit> getUnits() {
return units;
}

public Compartment(String itemId, List<Unit> units) {
this.itemId = itemId;
this.units = units;
}
}

public class Unit {
private final String containerNumber;

public String getContainerNumber() {
return containerNumber;
}

public Unit(String containerNumber) {
this.containerNumber = containerNumber;
}
}

鉴于这些类,我想提出一个列表、映射、元组或类型:itemIdcontainerNumber组合及其数量。

也就是说,如果我有:

Unit unit1 = new Unit("unit");
Unit unit2 = new Unit("unit");
Unit unit3 = new Unit("another_unit");

Compartment compartment = new Compartment("foo", newArrayList(unit1, unit2, unit3));

Supply supply = new Supply(newArrayList(compartment));

使用 Java 流,我想得到如下内容:

"foo", "unit", 2
"foo", "another_unit", 1

我已经尝试了一些与 groupingBytoMap 等的组合,但没有这样的运气。

我最近的尝试是这样的:

Map<String, List<Map<String, List<Unit>>>> result = supply.getCompartments()
.stream()
.collect(groupingBy(Compartment::getItemId,
mapping(compartment -> compartment.getUnits().stream().collect(groupingBy(Unit::getContainerNumber)), toList())));

我觉得这很接近,但我想我不能使用 Map,因为 key itemId 可能会多次使用不同的 容器编号

最佳答案

你的想法是正确的。您缺少的是您需要平面映射收集器而不是映射收集器作为下游收集器。

遗憾的是,这个收集器并没有内置在 Java 8 中,但它将出现在 Java 9 ( JDK-8071600 ) 中,带有 Collectors.flatMapping(mapper, downstream) .对于 Java 8,可以像这样重新实现它:

static <T,U,A,R> Collector<T,?,R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper, Collector<? super U, A, R> downstream) {
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
return Collector.of(
downstream.supplier(),
(acc, t) -> {
try (Stream<? extends U> stream = mapper.apply(t)) {
if (stream != null) {
stream.sequential().forEach(u -> downstreamAccumulator.accept(acc, u));
}
}
},
downstream.combiner(),
downstream.finisher(),
downstream.characteristics().toArray(new Characteristics[downstream.characteristics().size()])
);
}

然后你可以使用这个收集器来构建你想要的 map :

Map<String, Map<String, List<Unit>>> map =
supply.getCompartments()
.stream()
.collect(groupingBy(
Compartment::getItemId,
flatMapping(c -> c.getUnits().stream(), groupingBy(Unit::getContainerNumber))
));

关于java - 使用流对深层嵌套列表进行分组和求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36799530/

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