701 Stimmen

Java 8 Distinct nach Eigenschaft

In Java 8, wie kann ich eine Sammlung mithilfe der Stream-API filtern, indem ich die Eindeutigkeit einer Eigenschaft jedes Objekts überprüfe?

Zum Beispiel habe ich eine Liste von Person-Objekten und möchte Personen mit dem gleichen Namen entfernen,

persons.stream().distinct();

Verwendet den Standard-Gleichheitscheck für ein Person-Objekt, daher benötige ich etwas wie,

persons.stream().distinct(p -> p.getName());

Leider hat die distinct()-Methode keine solche Überladung. Ist es möglich, dies ohne Änderung des Gleichheitschecks innerhalb der Person-Klasse knapp zu tun?

13voto

Mateusz Rasiński Punkte 1176

Ich empfehle die Verwendung von Vavr, wenn möglich. Mit dieser Bibliothek können Sie Folgendes tun:

io.vavr.collection.List.ofAll(persons)
                       .distinctBy(Person::getName)
                       .toJavaSet() // oder eine andere Java 8-Sammlung

13voto

Naveen Dhalaria Punkte 133

Eine Liste von eindeutigen Objekten kann mit folgendem Code gefunden werden:

 List distinctPersons = persons.stream()
                    .collect(Collectors.collectingAndThen(
                            Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))),
                            ArrayList::new));

12voto

Enginer Punkte 2706

Sie können dieStreamEx-Bibliothek verwenden:

StreamEx.of(persons)
        .distinct(Person::getName)
        .toList()

10voto

Wojciech Górski Punkte 925

Erweiterung der Antwort von Stuart Marks, dies kann auf eine kürzere Art und Weise und ohne eine ConcurrentHashMap (wenn Sie keine parallelen Streams benötigen) gemacht werden:

public static  Predicate distinctByKey(Function keyExtractor) {
    final Set seen = new HashSet<>();
    return t -> seen.add(keyExtractor.apply(t));
}

Dann rufen Sie auf:

persons.stream().filter(distinctByKey(p -> p.getName());

8voto

Tomasz Linkowski Punkte 4186

Eine weitere Bibliothek, die dies unterstützt, ist jOO, sowie seine Seq.distinct(Function) Methode:

Seq.seq(persons).distinct(Person::getName).toList();

Unter der Haube macht es praktisch dasselbe wie die akzeptierte Antwort.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X