在Java 8中排序和分组并找到每个组的最大值

时间:2019-06-19 12:06:29

标签: java sorting comparator

我有一个具有名称和分数的对象。我想按名称对元素进行排序,并找到该名称的最高分。

例如以下是对象(名称,分数):

(a, 3)
(a, 9)
(b, 7)
(b, 10)
(c, 8)
(c, 3)

输出应为

(a, 9)
(b, 10)
(c, 8)

我可以按下面的程序排序。但我找不到最大的

List<Record> result = list.stream()
        .sorted(Comparator.comparing(Record::score))
        .collect(Collectors.groupingBy(Record::name, LinkedHashMap::new, Collectors.toList()))
        .values().stream()
        .flatMap(Collection::stream)
        .collect(Collectors.toList());

2 个答案:

答案 0 :(得分:4)

您需要将maxBy链接到groupinhBy收藏者:

Map<String,Record> result = 
    list.stream()
        .sorted(Comparator.comparing(Record::score))
        .collect(Collectors.groupingBy(Record::name, 
                                       LinkedHashMap::new,
                                       Collectors.maxBy(Comparator.comparing(Record::getScore))));

如果只关心Record实例,则可以获得该values()的{​​{1}}。

答案 1 :(得分:0)

@Eran的回答很好。不过,我将通过另一种方式进行相反的处理:首先分组然后减少:

List<Record> result = list.stream()
                              .collect(Collectors.groupingBy(Record::getName, 
                                      Collectors.maxBy(Comparator.comparing(Record::getScore))))
                              .values().stream()
                              .map(Optional::get)
                              .collect(Collectors.toList());

这里的缺点是您必须调用optional#get。但是,由于groupingBy产生的组永远不会为空,因此可以调用Optional#get并获取异常。