title: Java 8 Stream API - Selecting only values after Collectors.groupingBy(..)
body: <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>