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?

28voto

frhack Punkte 4410

Wir können auch RxJava verwenden (sehr leistungsstarke reaktive Erweiterung Bibliothek)

Observable.from(persons).distinct(Person::getName)

oder

Observable.from(persons).distinct(p -> p.getName())

24voto

Saeed Zarinfam Punkte 9384

Sie können den groupingBy Collector verwenden:

persons.collect(Collectors.groupingBy(p -> p.getName()))
        .values()
        .forEach(t -> System.out.println(t.get(0).getId()));

Wenn Sie einen anderen Stream haben möchten, können Sie dies verwenden:

persons.collect(Collectors.groupingBy(p -> p.getName()))
        .values()
        .stream()
        .map(l -> l.get(0));

15voto

Alex Punkte 1960

Ein ähnlicher Ansatz wie der von Saeed Zarinfam, aber mehr im Java-8-Stil :)

persons.collect(Collectors.groupingBy(p -> p.getName())).values().stream()
 .map(plans -> plans.stream().findFirst().get())
 .collect(toList());

14voto

Craig P. Motlin Punkte 26028

Sie können die distinct(HashingStrategy) Methode in Eclipse Collections verwenden.

List persons = ...;
MutableList distinct =
    ListIterate.distinct(persons, HashingStrategies.fromFunction(Person::getName));

Wenn Sie persons umbauen können, um eine Eclipse Collections-Schnittstelle zu implementieren, können Sie die Methode direkt auf der Liste aufrufen.

MutableList persons = ...;
MutableList distinct =
    persons.distinct(HashingStrategies.fromFunction(Person::getName));

HashingStrategy ist einfach eine Strategie-Schnittstelle, die es Ihnen ermöglicht, benutzerdefinierte Implementierungen von equals und hashcode zu definieren.

public interface HashingStrategy
{
    int computeHashCode(E object);
    boolean equals(E object1, E object2);
}

Hinweis: Ich bin ein Committer für Eclipse Collections.

14voto

uneq95 Punkte 2188

Mein Ansatz besteht darin, alle Objekte mit der gleichen Eigenschaft zusammenzufassen, die Gruppen dann auf eine Größe von 1 zu reduzieren und sie schließlich als Liste zu sammeln.

List listWithDistinctPersons = persons.stream()
            //Operatoren zum Entfernen von Duplikaten basierend auf dem Namen der Person
            .collect(Collectors.groupingBy(p -> p.getName()))
            .values()
            .stream()
            //Reduziere die Gruppen auf die Größe von 1
            .flatMap(group -> group.stream().limit(1))
            //Sammle eindeutige Benutzer als Liste
            .collect(Collectors.toList());

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