我有一个Map<String, List<SomeClassA>>
,我试图转换为Map<String, Map<String, List<SomeWrapperOfClassA>>>
,而我在如何解决这个问题时遇到了很多麻烦。
实际上,创建地图所需的所有信息都应该在SomeClassA类型的对象中 - 比如说
SomeClassA:
String attributeA;
String attributeB;
SomeClassB someOtherInfo;
SomeClassB:
String attribute C;
我想说它是基于此的地图:
Map<attributeA's values,Map<attribute C vals, List SomeWrapperOfClassA>>
其中列表只包含具有attributeA和attributeB值的SomeWrapperClassA。我当时认为它可能与groupingBy有关,但我不太熟悉如何以这样的方式嵌套它。
(或者为了简单起见,将SomeClassA的原始列表添加到Map<String, Map<String, List<SomeClassA>>>
中的任何帮助都已经是一个巨大的帮助。
我还没有完全掌握Java 8和更复杂的流媒体概念,所以一些帮助将不胜感激。我只熟悉基础知识。
答案 0 :(得分:0)
我不确定你的意思是:
Map<String, Map<String, List<SomeClassA>>>
,分组的关键是什么?一般来说,如果你想通过someClassA中的attributeA对List<SomeClassA>
进行分组,你可以这样做:
List<SomeClassA>.stream().collect(Collectors.groupingBy(someClsA-> someClsA.getAttributeA()));
答案 1 :(得分:0)
如果我理解你的问题,我会表达如下:
假设:
class ClassA {
public String getA();
public ClassB getB();
}
class ClassB {
public String getC();
}
Map<String, List<ClassA>> input;
我如何创建Map<String, Map<String, List<ClassB>>
,其中内部地图的键是getA
的结果?
如果这是正确的,那么你根本不想改变外部地图的键。这使它成为Map.replaceAll
的合适人选。为了清楚起见,我将收集器拆分为一个单独的方法,以便清楚发生了什么:
input.replaceAll(listA.stream().collect(mapCollector()));
private Collector<A, ?, Map<String, List<B>> mapCollector() {
return Collectors.groupingBy(ClassA::getA,
Collectors.mapping(ClassA::getB,
Collectors.toList()));
}
通过A
作为关键字解释组getA
的方法,然后使用A
通过映射收集这些getB
,然后放入列表。
如果您特别想要新地图(而不是更改原始地图),那么:
Map<String, Map<String, List<ClassB>>> output = input.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream().collect(mapCollector()));
答案 2 :(得分:0)
您想要实现的目标并不完全清楚。显然,源映射的键是无关紧要的,您只想处理值列表中包含的SomeClassA
实例。因此,第一步是流式传输地图的值,即sourceMap.values().stream()
,然后通过Stream<List<SomeClassA>>
将此Stream<SomeClassA>
展平为flatMap(List::stream)
。
通过其中一个属性对这些SomeClassA
实例进行分组,确实可以通过groupingBy
直接进行,这需要另一个嵌套groupingBy
来进一步按“属性C”对每个组进行分组:
Map<String, Map<String, List<SomeClassA>>> resultMap
= sourceMap.values().stream().flatMap(List::stream)
.collect(Collectors.groupingBy(SomeClassA::getAttributeA,
Collectors.groupingBy(a->a.getSomeOtherInfo().getAttributeC())));
要将SomeClassA
个实例转换为SomeWrapperClassA
个实例,我们需要另一个最内层groupingBy
的嵌套收集器; mapping
收集器允许在传输到另一个收集器之前映射值,该收集器必须是toList()
收集器,以前是隐含的。
现在,开始使用import static java.util.stream.Collectors.*;
Map<String, Map<String, List<SomeWrapperClassA>>> resultMap
= sourceMap.values().stream().flatMap(List::stream)
.collect(groupingBy(SomeClassA::getAttributeA, groupingBy(
a -> a.getSomeOtherInfo().getAttributeC(),
mapping(a->new SomeWrapperClassA(a.getAttributeA(),a.getAttributeB()), toList()))));