Java 8 ( 2014 ) löst dieses Problem mithilfe von Streams und Lambdas in einer Codezeile:
List<Person> beerDrinkers = persons.stream()
.filter(p -> p.getAge() > 16).collect(Collectors.toList());
Hier ist ein Tutorial .
Verwenden Sie Collection#removeIf
diese Option, um die vorhandene Sammlung zu ändern. (Hinweis: In diesem Fall entfernt das Prädikat Objekte, die das Prädikat erfüllen.)
persons.removeIf(p -> p.getAge() <= 16);
Mit Lambdaj können Sammlungen gefiltert werden, ohne Schleifen oder innere Klassen zu schreiben:
List<Person> beerDrinkers = select(persons, having(on(Person.class).getAge(),
greaterThan(16)));
Können Sie sich etwas Lesbareres vorstellen?
Haftungsausschluss: Ich bin ein Mitwirkender bei Lambdaj
persons.removeIf(p -> p.getAge() <= 16);
Angenommen, Sie verwenden Java 1.5 und können keine Google-Sammlungen hinzufügen , würde ich etwas sehr Ähnliches tun wie die Google-Mitarbeiter. Dies ist eine leichte Variation von Jons Kommentaren.
Fügen Sie diese Schnittstelle zuerst Ihrer Codebasis hinzu.
Die Implementierer können antworten, wenn ein bestimmtes Prädikat für einen bestimmten Typ gilt. ZB wenn
T
wärenUser
undAuthorizedUserPredicate<User>
implementiertIPredicate<T>
, dannAuthorizedUserPredicate#apply
kehrt ob das übergebene inUser
autorisiert ist.Dann könnte man in einer Utility-Klasse sagen
Angenommen, Sie haben die oben genannte Verwendung
Wenn die Leistung bei der linearen Prüfung von Bedeutung ist, möchte ich möglicherweise ein Domänenobjekt mit der Zielsammlung haben. Das Domänenobjekt mit der Zielsammlung verfügt über eine Filterlogik für die Methoden, mit denen die Zielsammlung initialisiert, hinzugefügt und festgelegt wird.
AKTUALISIEREN:
In der Utility-Klasse (sagen wir Prädikat) habe ich eine Auswahlmethode mit einer Option für den Standardwert hinzugefügt, wenn das Prädikat nicht den erwarteten Wert zurückgibt, sowie eine statische Eigenschaft für Parameter, die innerhalb des neuen IPredicate verwendet werden sollen.
Im folgenden Beispiel wird nach fehlenden Objekten zwischen Sammlungen gesucht:
Im folgenden Beispiel wird nach einer Instanz in einer Sammlung gesucht und das erste Element der Sammlung als Standardwert zurückgegeben, wenn die Instanz nicht gefunden wird:
UPDATE (nach Java 8):
Es ist einige Jahre her, seit ich (Alan) diese Antwort zum ersten Mal gepostet habe, und ich kann immer noch nicht glauben, dass ich SO-Punkte für diese Antwort sammle. Auf jeden Fall wäre meine Antwort jetzt, da Java 8 die Sprache geschlossen hat, erheblich anders und einfacher. Unter Java 8 ist keine eindeutige statische Dienstprogrammklasse erforderlich. Wenn Sie also das erste Element finden möchten, das Ihrem Prädikat entspricht.
Die JDK 8 API für optionals hat die Fähigkeit zu
get()
,isPresent()
,orElse(defaultUser)
,orElseGet(userSupplier)
undorElseThrow(exceptionSupplier)
, wie auch andere ‚monadischen‘ Funktionen, wiemap
,flatMap
undfilter
.Wenn Sie einfach alle Benutzer erfassen möchten, die dem Prädikat entsprechen,
Collectors
beenden Sie den Stream in der gewünschten Sammlung mit.Sehen Sie hier für weitere Beispiele, wie Java 8 - Streams zu arbeiten.
quelle
val authorized = for (user <- users if user.isAuthorized) yield user
Verwenden Sie CollectionUtils.filter (Collection, Predicate) von Apache Commons.
quelle
"Bester" Weg ist eine zu breite Anfrage. Ist es "am kürzesten"? "Am schnellsten"? "Lesbar"? An Ort und Stelle oder in eine andere Sammlung filtern?
Der einfachste (aber nicht am besten lesbare) Weg besteht darin, ihn zu iterieren und die Methode Iterator.remove () zu verwenden:
Um die Lesbarkeit zu verbessern, können Sie es jetzt in eine Dienstprogrammmethode einbinden. Erfinden Sie dann eine IPredicate-Schnittstelle, erstellen Sie eine anonyme Implementierung dieser Schnittstelle und führen Sie Folgendes aus:
Dabei filtert filterInPlace () die Auflistung und ruft Predicate.keepIt () auf, um zu erfahren, ob die Instanz in der Auflistung beibehalten werden soll.
Ich sehe keine Rechtfertigung dafür, eine Bibliothek eines Drittanbieters nur für diese Aufgabe einzubringen.
quelle
stream()
Feature geben, aber nicht jeder kann mit den neuesten Spielzeugen spielen: PBetrachten Sie Google Collections für ein aktualisiertes Collections-Framework, das Generika unterstützt.
UPDATE : Die Google-Sammlungsbibliothek ist jetzt veraltet. Sie sollten stattdessen die neueste Version von Guava verwenden. Es verfügt weiterhin über dieselben Erweiterungen des Sammlungsframeworks, einschließlich eines Mechanismus zum Filtern basierend auf einem Prädikat.
quelle
Warten Sie auf Java 8:
quelle
personList.removeIf(p -> p.age < 30);
Weniger ausführlich. Außerdem habe ich gehört, dass mit der Implementierung von APIs begonnen wird, dieStream
s anstelle vonCollection
s akzeptieren und zurückgeben, daStream
s sehr nützlich und schnell sind, aber das Gehen zu / von ihnen langsam ist.Seit der frühen Version von Java 8 können Sie Folgendes ausprobieren:
Wenn Sie beispielsweise eine Liste von Ganzzahlen hatten und die Zahlen filtern möchten, die> 10 sind, und diese Zahlen dann auf der Konsole ausdrucken möchten, können Sie Folgendes tun:
quelle
Ich werde RxJava in den Ring werfen , der auch für Android verfügbar ist . RxJava ist möglicherweise nicht immer die beste Option, bietet Ihnen jedoch mehr Flexibilität, wenn Sie Ihrer Sammlung mehr Transformationen hinzufügen oder Fehler beim Filtern behandeln möchten.
Ausgabe:
Weitere Details zu RxJava
filter
finden Sie hier .quelle
Die Einrichtung:
Die Verwendung:
quelle
Wie wäre es mit einem einfachen und geradlinigen Java
Einfach, lesbar und leicht (und funktioniert in Android!). Wenn Sie jedoch Java 8 verwenden, können Sie dies in einer süßen Zeile tun:
Beachten Sie, dass toList () statisch importiert wird
quelle
Möchten Sie die Sammlung selbst und nicht einen Iterator filtern?
Siehe org.apache.commons.collections.iterators.FilterIterator
oder mit Version 4 von apache commons org.apache.commons.collections4.iterators.FilterIterator
quelle
Schauen wir uns an, wie Sie eine integrierte JDK-Liste und eine MutableList mithilfe von Eclipse-Sammlungen filtern .
Wenn Sie Zahlen unter 3 filtern möchten, erwarten Sie die folgenden Ausgaben.
Hier erfahren Sie, wie Sie mit einem Java 8-Lambda filtern können
Predicate
.Hier erfahren Sie, wie Sie mithilfe einer anonymen inneren Klasse filtern können
Predicate
.Hier sind einige Alternativen zum Filtern von JDK-Listen und Eclipse Collections MutableLists mithilfe der Predicates- Factory.
Hier ist eine Version, die dem Prädikat kein Objekt zuweist, indem stattdessen die Predicates2- Factory mit der
selectWith
Methode verwendet wird, die a verwendetPredicate2
.Manchmal möchten Sie nach einem negativen Zustand filtern. In Eclipse Collections gibt es eine spezielle Methode für diesen Aufruf
reject
.Die Methode
partition
gibt zwei Sammlungen zurück, die die Elemente enthalten, die von der ausgewählt und von der abgelehnt wurdenPredicate
.Hinweis: Ich bin ein Committer für Eclipse-Sammlungen.
quelle
removeIf
eine Liste erstellen oder Primitive festlegen?Mit dem ForEach DSL können Sie schreiben
Bei einer Sammlung von [Der, schnelle, braune, Fuchs, springt, über, der, faule, Hund] ergibt sich [schnell, braun, springt, über, faul], dh alle Zeichenfolgen sind länger als drei Zeichen.
Alle von ForEach DSL unterstützten Iterationsstile sind
AllSatisfy
AnySatisfy
Collect
Counnt
CutPieces
Detect
GroupedBy
IndexOf
InjectInto
Reject
Select
Weitere Informationen finden Sie unter https://www.iam.unibe.ch/scg/svn_repos/Sources/ForEach
quelle
Die Collections2.filter- Methode (Collection, Predicate) in der Guava-Bibliothek von Google macht genau das, wonach Sie suchen.
quelle
Da Java 9
Collectors.filtering
aktiviert ist:Daher sollte die Filterung wie folgt sein:
Beispiel:
quelle
Dies, zusammen mit dem Mangel an echten Abschlüssen, ist mein größter Kritikpunkt für Java. Ehrlich gesagt sind die meisten der oben genannten Methoden ziemlich einfach zu lesen und WIRKLICH effizient. Nachdem Sie jedoch Zeit mit .Net, Erlang usw. verbracht haben, macht das auf Sprachebene integrierte Listenverständnis alles so viel sauberer. Ohne Ergänzungen auf Sprachebene kann Java nicht so sauber sein wie viele andere Sprachen in diesem Bereich.
Wenn die Leistung ein großes Problem darstellt, sind Google-Sammlungen der richtige Weg (oder schreiben Sie Ihr eigenes einfaches Prädikat-Dienstprogramm). Die Lambdaj-Syntax ist für manche Menschen besser lesbar, aber nicht ganz so effizient.
Und dann gibt es eine Bibliothek, die ich geschrieben habe. Ich werde alle Fragen bezüglich seiner Effizienz ignorieren (ja, es ist so schlimm) ...... Ja, ich weiß, dass es eindeutig auf Reflexion basiert, und nein, ich benutze es nicht wirklich, aber es funktioniert:
ODER
quelle
JFilter http://code.google.com/p/jfilter/ ist am besten für Ihre Anforderung geeignet.
JFilter ist eine einfache und leistungsstarke Open Source-Bibliothek zum Abfragen der Sammlung von Java-Beans.
Hauptmerkmale
quelle
Ich habe eine erweiterte Iterable-Klasse geschrieben , die das Anwenden funktionaler Algorithmen unterstützt, ohne den Sammlungsinhalt zu kopieren.
Verwendungszweck:
Der obige Code wird tatsächlich ausgeführt
quelle
Verwenden Sie die Collection Query Engine (CQEngine) . Dies ist bei weitem der schnellste Weg.
Siehe auch: Wie fragen Sie Objektsammlungen in Java ab (Kriterien / SQL-ähnlich)?
quelle
Einige wirklich tolle tolle Antworten hier. Ich möchte Thins so einfach und lesbar wie möglich halten:
quelle
Die einfache Lösung vor Java8:
Leider ist diese Lösung nicht vollständig generisch und gibt eher eine Liste als den Typ der angegebenen Sammlung aus. Das Einbringen von Bibliotheken oder das Schreiben von Funktionen, die diesen Code umschließen, erscheint mir außerdem übertrieben, es sei denn, die Bedingung ist komplex, aber dann können Sie eine Funktion für die Bedingung schreiben.
quelle
https://code.google.com/p/joquery/
Unterstützt verschiedene Möglichkeiten,
Gegebene Sammlung,
vom Typ,
Filter
Java 7
Java 8
Ebenfalls,
Sortieren (auch für Java 7 verfügbar)
Gruppierung (auch für Java 7 verfügbar)
Joins (auch für Java 7 verfügbar)
Gegeben,
Kann verbunden werden wie,
Ausdrücke
quelle
Meine Antwort baut auf dem von Kevin Wong, hier als Einzeiler unter Verwendung
CollectionUtils
von Feder und einem Java 8 Lambda - Ausdruck.Dies ist so präzise und lesbar wie jede Alternative, die ich gesehen habe (ohne aspektbasierte Bibliotheken zu verwenden).
Spring CollectionUtils ist ab Spring Version 4.0.2.RELEASE verfügbar. Denken Sie daran, dass Sie JDK 1.8 und Sprachstufe 8+ benötigen.
quelle
Mit
java 8
speziell ,lambda expression
können Sie es einfach tun , wie das folgende Beispiel:Wenn für jede
product
internemyProducts
Sammlung, wennprod.price>10
, dann fügen Sie dieses Produkt der neuen gefilterten Liste hinzu.quelle
Ich musste eine Liste abhängig von den Werten filtern, die bereits in der Liste vorhanden sind. Entfernen Sie beispielsweise alle folgenden Werte, die kleiner als der aktuelle Wert sind. {2 5 3 4 7 5} -> {2 5 7}. Oder um beispielsweise alle Duplikate zu entfernen {3 5 4 2 3 5 6} -> {3 5 4 2 6}.
Dies wird so verwendet.
quelle
Mit Guave:
quelle
In Java 8 können Sie diese Filtermethode direkt verwenden und dies dann tun.
quelle