Java 8 Stream API - 在Collectors.groupingBy(..)之后仅选择值 [英] Java 8 Stream API - Selecting only values after Collectors.groupingBy(..)

查看:733
本文介绍了Java 8 Stream API - 在Collectors.groupingBy(..)之后仅选择值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下 Student 对象的集合,其中包括Name(String),Age(int)和City(String)。

Say I have the following collection of Student objects which consist of Name(String), Age(int) and City(String).

我正在尝试使用Java的Stream API来实现以下类似sql的行为:

I am trying to use Java's Stream API to achieve the following sql-like behavior:

SELECT MAX(age)
FROM Students
GROUP BY city

现在,我发现两种不同的方法:

Now, I found two different ways to do so:

final List<Integer> variation1 =
            students.stream()
                    .collect(Collectors.groupingBy(Student::getCity, Collectors.maxBy((s1, s2) -> s1.getAge() - s2.getAge())))
                    .values()
                    .stream()
                    .filter(Optional::isPresent)
                    .map(Optional::get)
                    .map(Student::getAge)
                    .collect(Collectors.toList());

另一个:

final Collection<Integer> variation2 =
            students.stream()
                    .collect(Collectors.groupingBy(Student::getCity,
                            Collectors.collectingAndThen(Collectors.maxBy((s1, s2) -> s1.getAge() - s2.getAge()),
                                    optional -> optional.get().getAge())))
                    .values();

两种方式都必须 .values()... 并过滤从收集器返回的空组。

In both ways, one has to .values() ... and filter the empty groups returned from the collector.

是否有其他方法可以实现此要求的行为?

Is there any other way to achieve this required behavior?

这些方法提醒我超过分区 sql语句......

These methods remind me of over partition by sql statements...

谢谢

编辑:以下所有答案都非常有趣,但不幸的是,这不是我的意思寻找,因为我试图得到的只是价值观。我不需要键,只需要值。

All the answers below were really interesting, but unfortunately this is not what I was looking for, since what I try to get is just the values. I don't need the keys, just the values.

推荐答案

不要总是坚持 groupingBy 。有时 toMap 是你需要的东西:

Do not always stick with groupingBy. Sometimes toMap is the thing you need:

Collection<Integer> result = students.stream()
    .collect(Collectors.toMap(Student::getCity, Student::getAge, Integer::max))
    .values();

在这里你只需创建一个 Map 其中的键是城市,价值观是年龄。如果几个学生拥有相同的城市,则使用合并功能,这里只选择最大年龄。它更快更清洁。

Here you just create a Map where keys are cities and values are ages. In case when several students have the same city, merge function is used which just selects maximal age here. It's faster and cleaner.

这篇关于Java 8 Stream API - 在Collectors.groupingBy(..)之后仅选择值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆