Java – use groupingby for nested maps, but collect different types of objects

So I have the code for this "work" (replace some names for simplicity):

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

However, I want to change this code so that after grouping through the someclassa field, the internal collection is someclassb For example, if the class looks like this:

Suppose they all have all args constructors

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

class SomeClassB {
    T someData;
    String someId; 
}

And there is one way:

public static Collection<SomeClassB> getSomeClassBsFromSomeClassA(SomeClassA someA) {
    List<Some List of Class B> listOfB = someMethod(someA);
    return listOfB; // calls something using someClassA,gets a list of SomeClassB 
}

I want to flatten the result list of someclass BS to

Map<String,ImmutableList<SomeClassB>>> someMap = 
    someListOfClassA.stream()
    .filter(...)
    . // not sure how to group by SomeClassA fields but result in a list of SomeClassB since one SomeClassA can result in multiple SomeClassB

I'm not sure how this will fit the code above How to collect a bunch of lists based on someclassb into a single list of all values of someclassa? If a single classA maps to a single ClassB, I know how to use collectors Mapping makes it work, but since each classA leads to multiple classbs, I don't know how to make it work

Any ideas would be appreciated thank you!

Solution

Use a custom collector like this:

private static Collector<Collection<SomeClassB>,?,ImmutableList<SomeClassB>>
        flatMapToImmutableList() {
        return Collectors.collectingAndThen(Collectors.toList(),listOfCollectionsOfB ->
                        listOfCollectionsOfB.stream()
                                .flatMap(Collection::stream)
                                .collect(GuavaCollectors.toImmutableList()));
    }

You can achieve your goals:

Map<String,List<SomeClassB>>> someMap =
                someListOfClassA.stream()
                        .filter(...)
                        .collect(Collectors.groupingBy(SomeClassA::getSomeCriteriaA,Collectors.groupingBy(SomeClassA::getSomeCriteriaB,Collectors.mapping(a -> getSomeClassBsFromSomeClassA(a),flatMapToImmutableList()))));
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>