5 Stimmen

Extrahieren von Objekten aus List<X> basierend auf einer anderen Listeneigenschaftssammlung

Ich habe eine Klasse -

public class Data implements Identifiable{
    private Integer id;

    public Integer getId(){
        return id;
    }
}

Jetzt habe ich zwei Sammlungen.

List<Data> data1 = // few hundred Objects

Set<Integer> dataIds = // few object ids

Ich würde gerne die List<Data> von data1 die über ids in dataIds

Wie sollte ich vorgehen? I'va Guava in meinem Klassenpfad so kann mit Guava's Functional Ansatz gehen, wenn vergleichbar in Leistung/Effizienz.

3voto

mindas Punkte 25933

Wie wäre es mit

Collections2.filter(
    data1,
    new Predicate<Data>() {
       public boolean apply(Data d) {
         return dataIds.contains(d.getId());
       }
    }
)

p.s. nicht zu kompliziert werden Dinge, wenn sie nicht wirklich notwendig sind.

3voto

ColinD Punkte 106101

Wenn Sie nicht nur einmal durch das Ergebnis iterieren wollen oder eine wiederverwendbare gefilterte Live-Ansicht benötigen, möchten Sie wahrscheinlich eine Liste mit den Übereinstimmungen erstellen, die nicht zur Ansicht gehört. Das Erstellen einer List ou Set um das Ergebnis zu speichern und dann durch die Datenliste zu iterieren und Übereinstimmungen hinzuzufügen, ist ein sehr guter Ansatz und leicht zu verstehen!

List<Data> result = Lists.newArrayList();
for (Data data : data1) {
  if (dataIds.contains(data.getId()))
    result.add(data);
}

Ich sehe Ihre Data Klasse implementiert eine Identifiable Schnittstelle. In diesem Fall könnten Sie eine Function<Identifiable, Integer> der die ID erhält... Identifiables.getIdFunction() oder so ähnlich. Das ist schön, weil es wahrscheinlich auch an anderen Stellen nützlich sein kann (ich spreche über diesen Ansatz in einem Blogbeitrag aquí ). Damit wäre es auch mit Guava recht einfach, dies zu tun:

Predicate<Identifiable> predicate = Predicates.compose(
    Predicates.in(dataIds), Identifiables.getIdFunction());
List<Data> filtered = Lists.newArrayList(Iterables.filter(data1, predicate));

Dies entspricht im Wesentlichen dem ersten Beispiel, scheint aber schwieriger zu verstehen zu sein. Da es keinen eindeutigen Vorteil gibt, dies zu tun (anders als in einer Situation, in der Sie nur die Live-Ansicht verwenden möchten), wäre meine Empfehlung, nur mit dem ersten zu gehen.

0voto

Eero Anttila Punkte 11

Con LambdaJ könnten Sie schreiben:

List<Data> result = extract(data1, on(Data.class).getId());

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