gpt4 book ai didi

java-8 - 如何使用 Collectors.toMap 从具有列表的对象集中收集 map

转载 作者:行者123 更新时间:2023-12-02 01:02:47 24 4
gpt4 key购买 nike

我有一个带有列表的类 Element,我的预期输出是这样的: Map<String , List<Element>>

{
1 = [Element3, Element1],
2 = [Element2, Element1],
3 = [Element2, Element1], 4=[Element2]
}

我的输入是一组元素对象,我使用了forEach以获得所需的结果,但我正在寻找如何使用 collectors.toMap 收集它.非常感谢任何输入

Set<Element> changes = new HashSet();

List<String> interesetList = new ArrayList();
interesetList.add("1");
interesetList.add("2");
interesetList.add("3");

Element element = new Element(interesetList);
changes.add(element);

interesetList = new ArrayList();
interesetList.add("2");
interesetList.add("3");
interesetList.add("4");

element = new Element(interesetList);
changes.add(element);

Map<String, List<Element>> collect2 = new HashMap();

changes.forEach(element -> {
element.getInterestedList().forEach(tracker -> {
collect2.compute(tracker, ( key , val) -> {
List<Element> elementList = val == null ? new ArrayList<Element>() : val;
elementList.add(Element);
return elementList;
});
});
});


class Element {

List<String> interestedList;
static AtomicInteger sequencer = new AtomicInteger(0);
String mName;
public Element(List<String> aList) {
interestedList = aList;
mName = "Element" + sequencer.incrementAndGet();
}
public List<String> getInterestedList() {
return interestedList;
}
@Override
public String toString() {
return mName;
}
}

最佳答案

您可以使用 Collectors.groupingBy 来完成而不是 Collectors.toMap , 以及 Collectors.mapping ,它使一个收集器适应另一个收集器:

Map<String, List<Element>> result = changes.stream()
.flatMap(e -> e.getInterestedList().stream().map(t -> Map.entry(t, e)))
.collect(Collectors.groupingBy(
Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

您需要使用 Stream.flatMap方法,然后将内部列表的元素与当前 Element 配对实例。我通过新的 Java 9 的 Map.entry(key, value) 做到了这一点方法。如果你还没有使用 Java 9,你可以将其更改为 new AbstractMap.SimpleEntry<>(key, value) .

平面映射后,我们需要收集 Map.Entry 的实例.所以我正在使用 Collectors.groupingBy按键对条目进行分类(我们之前存储了内部列表的每个元素,也就是您在代码中所说的 tracker)。然后,因为我们不想拥有 List<Map.Entry<String, Element>> 的实例作为 map 的值,我们需要转换每个 Map.Entry<String, Element>流到 Element (这就是为什么我使用 Map.Entry::getValue 作为 Collectors.mapping 的第一个参数)。我们还需要指定下游收集器(此处为 Collectors.toList() ),以便外部 Collectors.groupingBy收集器知道在哪里放置属于每个组的流的所有适应元素。


一种更短且肯定更有效的方法(类似于您的尝试)可能是:

Map<String, List<Element>> result = new HashMap<>();
changes.forEach(e ->
e.getInterestedList().forEach(t ->
result.computeIfAbsent(t, k -> new ArrayList<>()).add(e)));

这使用 Map.computeIfAbsent ,非常适合您的用例。

关于java-8 - 如何使用 Collectors.toMap 从具有列表的对象集中收集 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49413718/

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