使用Java 8将对象按两个字段分组

时间:2019-01-17 15:57:49

标签: java collections java-8 java-stream grouping

我在用Java 8分组两个值时遇到问题。

我的主要问题是对两个字段进行分组,我正确地对一个名为getNameOfCountryOrRegion()的字段进行了分组,但是现在我对groupingBy感兴趣的另一个字段也称为leagueDTO

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

以及以下课程:

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

结果将按nameOfCountryOrRegionleagueDTO分组。

4 个答案:

答案 0 :(得分:4)

downstream收集器传递给groupingBy将达到目的:

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

上面的代码段会将FullCalendarDTO对象按nameOfCountryOrRegion分组,然后将每个组按leagueDTO分组。

所以返回的集合看起来像Map<String, Map<String, List<FullCalendarDTO>>>

答案 1 :(得分:3)

如果要使用两个属性进行分组,则输出将是一个Map,其键为用于分组的第一个属性getNameOfCountryOrRegion),而值作为再次Map,并使用键作为用于第二个属性进行分组的getLeagueDTO),并将其值作为List<FullCalendarDTO>,并根据指定的键进行分组。

这看起来像:

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

答案 2 :(得分:1)

Collectors类的groupingBy()方法支持一个附加的Collector作为第二个参数:

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

上面可以写到groupBy()两个值

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

答案 3 :(得分:0)

如果您要查找原始列表以将其分组到Maps中。 下面是代码片段

    List<FullCalendarDTO> arrayList = new ArrayList<FullCalendarDTO>();
    arrayList.add(new FullCalendarDTO("US","A"));
    arrayList.add(new FullCalendarDTO("EU","A"));
    arrayList.add(new FullCalendarDTO("EU","A"));
    arrayList.add(new FullCalendarDTO("US","A"));
    arrayList.add(new FullCalendarDTO("US","B"));

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

    HashMap<String, Map<String, List<FullCalendarDTO>>> finalOutput = new HashMap<String, Map<String, List<FullCalendarDTO>>>();
    for (Entry<String, List<FullCalendarDTO>> fullCalendarDTO : result.entrySet()) {
        Map<String, List<FullCalendarDTO>> collect = fullCalendarDTO.getValue().stream().collect(Collectors.groupingBy(FullCalendarDTO::getLeagueDTO));
        finalOutput.put(fullCalendarDTO.getKey(), collect);
    }

    System.out.println(finalOutput);

输出

{EU = {A = [EU :: A,EU :: A]}},US = {A = [US :: A,US :: A],B = [US :: B]}} < / p>