2014-10-26 14 views
28

Oh, diese knifflige Java 8 Streams mit Lambdas. Sie sind sehr kraftvoll, doch die Feinheiten nehmen ein wenig zu viel Zeit in Anspruch, um den Header zu umhüllen.Sortieren nach Eigenschaft in Java 8 stream

Nehmen wir an, ich habe einen User Typ mit einer Eigenschaft User.getName(). Nehmen wir an, ich habe eine Karte dieser Benutzer Map<String, User> mit Namen verbunden (Login Benutzernamen, zum Beispiel). Lassen Sie uns weiter sagen, ich habe eine Instanz eines Komparators UserNameComparator.INSTANCE, um Benutzernamen zu sortieren (vielleicht mit ausgefallenen Kollatoren und so).

Wie bekomme ich eine Liste der Benutzer in der Karte, sortiert nach Benutzername? Ich kann die Karte Schlüssel ignorieren und tun dies:

return userMap.values() 
    .stream() 
    .sorted((u1, u2) -> { 
     return UserNameComparator.INSTANCE.compare(u1.getName(), u2.getName()); 
    }) 
    .collect(Collectors.toList()); 

Aber diese Linie, wo ich den Namen zu extrahieren haben die UserNameComparator.INSTANCE scheint, wie zu viel manuelle Arbeit zu verwenden. Gibt es eine Möglichkeit, kann ich einfach liefern User::getName als Mapping-Funktion, nur für die Sortierung, und immer noch die User Instanzen zurück in der gesammelten Liste?

Bonus: Was wäre, wenn die Sache, die ich sortieren wollte, zwei Ebenen tief war, wie User.getProfile().getUsername()?

Antwort

51

Was Sie wollen, ist Comparator#comparing:

userMap.values().stream() 
    .sorted(Comparator.comparing(User::getName, UserNameComparator.INSTANCE)) 
    .collect(Collectors.toList()); 

Für den zweiten Teil Ihrer Frage, würden Sie nur

verwenden
Comparator.comparing(
    u->u.getProfile().getUsername(), 
    UserNameComparator.INSTANCE 
) 
+0

Wow, fast mein Gehirn tut weh, aber das war genau das, was ich suchte für, Bonus und alles! Und super schnelle Antwort auch. Vielen Dank! –