Java 8 Stream API - Selecting only values after Collectors.groupingBy(..)
<p>Say I have the following collection of <code>Student</code> objects which consist of Name(String), Age(int) and City(String).</p>

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

<pre><code>SELECT MAX(age)
FROM Students
GROUP BY city
</code></pre>

<p>Now, I found two different ways to do so:</p>

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

<p>And the other one:</p>

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

<p>In both ways, one has to <code>.values() ...</code> and filter the empty groups returned from the collector.</p>

<p>Is there any other way to achieve this required behavior?</p>

<p>These methods remind me of <code>over partition by</code> sql statements...</p>

<p>Thanks</p>

<hr>

<p><strong>Edit:</strong> 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.</p>