2017-04-12 57 views
1

,所以我有这样的代码,“工程”(更换一些名称为简单起见):创建使用GROUPBY嵌套地图,收集到不同类型的对象

Map<String, Map<String, ImmutableList<SomeClassA>>> someMap = 
     someListOfClassA.stream() 
     .filter(...) 
     .collect(Collectors.groupingBy(SomeClassA::someCriteriaA, 
      Collectors.groupingBy(SomeClassA::someCriteriaB, GuavaCollectors.toImmutableList() 
      ) 
    )); 

不过,我想改变这个代码,以便相反,我们在分组SomeClassA之后创建新的SomeClassB。因此,如果类是这样的:

因此,例如,(假设他们都已经全部ARGS构建

class SomeClassA { 
    String someCriteriaA; 
    String someCriteriaB; 
    T someData; 
    String someId; 
} 

class SomeClassB { 
    T someData; 
    String someId; 
} 

我希望能够改为建立

Map<String, Map<String, ImmutableList<SomeClassB>>> someMap = 
    someListOfClassA.stream() 
    .filter(...) 
    . // not sure how to group by SomeClassA values while creating new SomeClassB instances 

我我不知道这将如何适合上面的代码。我如何构建SomeClassB基于SomeClassA的值实例?

任何想法,将不胜感激!

+2

'Collectors.mapping(SomeClassB :: new,GuavaCollectors.toImmutableList())' – 4castle

+0

@ 4castle - 你能提供一些关于如何工作的细节吗?你如何从分组的SomeClassA对象中获取值到新创建的SomeClassB实例中? – Otter

+1

'SomeClassB :: new'可以用任何将某个'SomeClassA'实例转换为'SomeClassB'的lambda或方法引用来替换。 'Collectors.mapping'只是在收集下游收集器中的输出之前通过函数运行该值。 – 4castle

回答

0

使用收藏家那样:

Map<String, Map<String, ImmutableList<SomeClassB>>> someMap = 
    someListOfClassA 
    .stream() 
    .filter(...) 
    .collect(Collectors.groupingBy(SomeClassA::someCriteriaA, 
       Collectors.groupingBy(SomeClassA::someCriteriaB, 
       Collectors.mapping(someClassA -> new SomeClassB(), GuavaCollectors.toImmutableList())))); 

尽管你可以用你的代码替换someClassA -> new SomeClassB()SomeClassA实例转换到SomeClassB一个实例。

Collectors.mapping()只会在收集发生之前应用给定的函数。