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?

0voto

anshul dubey Punkte 51

Da jeder seine eigenen Ideen und Implementierungen teilt, habe auch ich eine, die nicht effizient ist, aber funktioniert:

Set personNameList = personList.stream().
map(tempPerson->tempPerson.getName()).collect(Collectors.toSet());

personList.stream().
                   collect(()->new ArrayList(),
                           (l1,p)->{
                                  if(!personNameList.contains(p.getName())) {
                                        l1.add(p);
                                  }
        }, ArrayList::addAll);

-1voto

Flavio Oliva Punkte 509

In meinem Fall musste ich kontrollieren, was das vorherige Element war. Ich habe dann ein zustandsbezogenes Prädikat erstellt, bei dem ich kontrolliert habe, ob das vorherige Element vom aktuellen Element abweicht, in diesem Fall habe ich es behalten.

public List fetchLogById(Long id) {
    return this.findLogById(id).stream()
        .filter(new LogPredicate())
        .collect(Collectors.toList());
}

public class LogPredicate implements Predicate {

    private Log previous;

    public boolean test(Log current) {
        boolean isDifferent = previous == null || verifyIfDifferentLog(current, previous);

        if (isDifferent) {
            previous = current;
        }
        return isDifferent;
    }

    private boolean verifyIfDifferentLog(Log current, Log previous) {
        return !current.getId().equals(previous.getId());
    }

}

-3voto

Abdur Rahman Punkte 1102

Wenn Sie eine Liste von Personen möchten, wäre folgender Weg einfach

Set set = new HashSet<>(persons.size());
persons.stream().filter(p -> set.add(p.getName())).collect(Collectors.toList());

Zusätzlich können Sie auch mit den folgenden beiden Methoden eine distinkte oder eindeutige Liste von Namen, nicht Personen finden.

Methode 1: Verwendung von distinct

persons.stream().map(x->x.getName()).distinct.collect(Collectors.toList());

Methode 2: Verwendung von HashSet

Set set = new HashSet<>();
set.addAll(person.stream().map(x->x.getName()).collect(Collectors.toList()));

-3voto

Franz Punkte 189

Was ist mit dieser Lösung.

Es funktioniert nur, wenn Ihr Schlüssel Equal implementiert, was die meisten Basistypen tun, aber es ist ein wenig einfacher.

person.stream().map(person -> p.getName()).distinct()

-4voto

2Big2BeSmall Punkte 1278

Der einfachste Code, den Sie schreiben können:

    persons.stream().map(x-> x.getName()).distinct().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