Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouping objects by two fields using Java 8

I have a problem grouping two values with Java 8.

My main problem is about grouping two fields, I group correctly one field called getNameOfCountryOrRegion() but now I am interested in groupingBy another field that is called leagueDTO as well.

Map<String, List<FullCalendarDTO>> result = countryDTOList.stream()
               .collect(Collectors.groupingBy(
                             FullCalendarDTO::getNameOfCountryOrRegion));

And the following class :

public class FullCalendarDTO  {
    private long id;
    private TeamDTO localTeam;
    private TeamDTO visitorTeam;
    private LocationDTO location;   
    private String leagueDTO;       
    private String timeStamp;
    private String nameOfCountryOrRegion;
}

The result will be grouped by nameOfCountryOrRegion and leagueDTO.

like image 664
kikes Avatar asked Jan 17 '19 15:01

kikes


3 Answers

Passing a downstream collector to groupingBy will do the trick:

countryDTOList.stream()
              .collect(groupingBy(FullCalendarDTO::getNameOfCountryOrRegion,
                       groupingBy(FullCalendarDTO::getLeagueDTO)));

The code snippet above will group your FullCalendarDTO objects by nameOfCountryOrRegion then each group will be grouped by leagueDTO.

So the returned collection will look like Map<String, Map<String, List<FullCalendarDTO>>>.

like image 109
ETO Avatar answered Oct 05 '22 23:10

ETO


If you were to group by using two attributes, your output would be a Map with keys as the first attribute used to group(getNameOfCountryOrRegion) and values as a Map again with keys as the second attribute used to group(getLeagueDTO) and its values as a List<FullCalendarDTO> which are grouped based on the keys specified.

This shall look like :

Map<String, Map<String, List<FullCalendarDTO>>> result = countryDTOList.stream()
        .collect(Collectors.groupingBy(FullCalendarDTO::getNameOfCountryOrRegion,
                Collectors.groupingBy(FullCalendarDTO::getLeagueDTO)));
like image 27
Naman Avatar answered Oct 06 '22 00:10

Naman


Collectors class groupingBy() method supports an additional Collector as a second argument:

public static <T, K, A, D>    Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream)

The above can be written to groupBy() two values

Map<String, List<FullCalendarDTO>> result = countryDTOList.stream().collect(Collectors.groupingBy(FullCalendarDTO::getNameOfCountryOrRegion, Collectors.groupingBy(FullCalendarDTO::getLeagueDTO)));
like image 22
shasr Avatar answered Oct 06 '22 01:10

shasr