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

Shr*_*dha 3 java sorting comparator

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

例如,下面是对象(namescore):

(a, 3)
(a, 9)
(b, 7)
(b, 10)
(c, 8)
(c, 3)
Run Code Online (Sandbox Code Playgroud)

输出应为:

(a, 9)
(b, 10)
(c, 8)
Run Code Online (Sandbox Code Playgroud)

我可以使用以下代码进行排序,但无法找到最大

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());
Run Code Online (Sandbox Code Playgroud)

Eri*_*ean 7

@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());
Run Code Online (Sandbox Code Playgroud)

这里的一个缺点是你必须调用Optional#get。但由于 groupingBy 产生的组永远不会为空,因此您可以调用Optional#get而不会出现异常。


Era*_*ran 5

您需要链接maxBygroupinhBy收藏家:

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

如果你只关心Record的情况下,你可以得到values()的那个Map