it-swarm.com.de

So suchen Sie in einer Liste von Java-Objekten

Ich habe eine Objektliste und die Liste ist sehr groß. Das Objekt ist 

class Sample {
    String value1;
    String value2;
    String value3;
    String value4;
    String value5;
 }

Jetzt muss ich nach einem bestimmten Wert eines Objekts in der Liste suchen. Sagen Sie, ob value3=='three' ich diese Objekte zurückgeben muss (Meine Suche basiert nicht immer auf value3)

Die Liste ist 

List<Sample> list = new ArrayList<Sample>();

Was ist der effizienteste Weg, dies zu tun?

Vielen Dank.

24
Jeevi

Sie können versuchen, Apache Commons Collections .

Es gibt eine Klasse CollectionUtils , mit der Sie Elemente nach benutzerdefiniertem Predicate auswählen oder filtern können.

Ihr Code wäre so:

Predicate condition = new Predicate() {
   boolean evaluate(Object sample) {
        return ((Sample)sample).value3.equals("three");
   }
};
List result = CollectionUtils.select( list, condition );

Update:

In Java8, mit Lambdas und StreamAPI sollte dies Folgendes sein:

List<Sample> result = list.stream()
     .filter(item -> item.value3.equals("three"))
     .collect(Collectors.toList());

viel schöner!

39
Esteve

Java verwenden 8

Mit Java 8 können Sie Ihre Liste einfach in einen Stream umwandeln und so schreiben:

import Java.util.List;
import Java.util.stream.Collectors;

List<Sample> list = new ArrayList<Sample>();
List<Sample> result = list.stream()
    .filter(a -> Objects.equals(a.value3, "three"))
    .collect(Collectors.toList());

Beachten Sie, dass

  • a -> Objects.equals(a.value3, "three") ist ein Lambda-Ausdruck
  • result ist eine List mit einem Sample-Typ
  • Es ist sehr schnell, kein Cast bei jeder Wiederholung
  • Wenn Ihre Filterlogik schwerer wird, können Sie list.parallelStream() anstelle von list.stream() ausführen ( lesen Sie diese )


Apache Commons

Wenn Sie Java 8 nicht verwenden können, können Sie Apache Commons library verwenden und schreiben:

import org.Apache.commons.collections.CollectionUtils;
import org.Apache.commons.collections.Predicate;

Collection result = CollectionUtils.select(list, new Predicate() {
     public boolean evaluate(Object a) {
         return Objects.equals(((Sample) a).value3, "three");
     }
 });

// If you need the results as a typed array:
Sample[] resultTyped = (Sample[]) result.toArray(new Sample[result.size()]);

Beachten Sie, dass:

  • Bei jeder Iteration gibt es einen Cast von Object nach Sample
  • Wenn Sie Ihre Ergebnisse als Sample[] eingeben möchten, benötigen Sie zusätzlichen Code (wie in meinem Beispiel gezeigt).



Bonus: A Nizza Blogartikel darüber reden, wie man ein Element in der Liste findet.

38
Yves M.

Wenn Sie immer nach value3 suchen, könnten Sie die Objekte in einer Map speichern:

Map<String, List<Sample>> map = new HashMap <>();

Sie können die Map dann mit key = value3 und value = Liste der Beispielobjekte mit derselben value3-Eigenschaft füllen.

Sie können dann die Karte abfragen:

List<Sample> allSamplesWhereValue3IsDog = map.get("Dog");

Hinweis: Wenn keine 2 Sample-Instanzen denselben value3 haben können, können Sie einfach einen Map<String, Sample> verwenden.

3
assylias

Ich modifiziere diese Liste und füge eine Liste zu den Beispielen hinzu

Pseudocode

Sample {
   List<String> values;
   List<String> getList() {
   return values}
}



for(Sample s : list) {
   if(s.getString.getList.contains("three") {
      return s;
   }
}
3
MemLeak

Da Ihre Liste eine ArrayList ist, kann davon ausgegangen werden, dass sie nicht sortiert ist. Daher können Sie nicht nach Ihrem Element suchen, das schneller als O(n) ist.

Wenn Sie können, sollten Sie überlegen, Ihre Liste in eine Set (mit HashSet als Implementierung) mit einer bestimmten Comparator für Ihre Beispielklasse zu ändern.

Eine andere Möglichkeit wäre die Verwendung einer HashMap. Sie können Ihre Daten als Sample hinzufügen (beginnen Sie die Klassennamen mit einem Großbuchstaben) und verwenden Sie die Zeichenfolge, nach der Sie suchen möchten. Dann könntest du einfach verwenden

Sample samp = myMap.get(myKey);

Wenn es mehrere Schlüssel pro Schlüssel gibt, verwenden Sie Map<String, List<Sample>>, andernfalls Map<String, Sample>. Wenn Sie mehrere Schlüssel verwenden, müssen Sie mehrere Karten erstellen, die dasselbe Dataset enthalten. Da alle auf die gleichen Objekte zeigen, sollte der Platz kein so großes Problem sein.

0
brimborium