Java 8 ( 2014 ) résout ce problème en utilisant des flux et des lambdas dans une seule ligne de code:
List<Person> beerDrinkers = persons.stream()
.filter(p -> p.getAge() > 16).collect(Collectors.toList());
Voici un tutoriel .
Utilisez Collection#removeIf
pour modifier la collection en place. (Remarque: dans ce cas, le prédicat supprimera les objets qui satisfont le prédicat):
persons.removeIf(p -> p.getAge() <= 16);
lambdaj permet de filtrer les collections sans écrire de boucles ni de classes internes:
List<Person> beerDrinkers = select(persons, having(on(Person.class).getAge(),
greaterThan(16)));
Pouvez-vous imaginer quelque chose de plus lisible?
Avertissement: je suis un contributeur sur lambdaj
persons.removeIf(p -> p.getAge() <= 16);
En supposant que vous utilisez Java 1.5 et que vous ne pouvez pas ajouter de collections Google , je ferais quelque chose de très similaire à ce que les gars de Google ont fait. Ceci est une légère variation sur les commentaires de Jon.
Ajoutez d'abord cette interface à votre base de code.
Ses implémenteurs peuvent répondre lorsqu'un certain prédicat est vrai d'un certain type. Par exemple, si
T
étaientUser
etAuthorizedUserPredicate<User>
implémenteIPredicate<T>
, puisAuthorizedUserPredicate#apply
retourne si la transmissionUser
est autorisée.Ensuite, dans une classe utilitaire, on pourrait dire
Donc, en supposant que vous utilisez ce qui précède, cela peut être
Si les performances de la vérification linéaire sont préoccupantes, je voudrais peut-être avoir un objet de domaine qui possède la collection cible. L'objet de domaine qui a la collection cible aurait une logique de filtrage pour les méthodes qui initialisent, ajoutent et définissent la collection cible.
MISE À JOUR:
Dans la classe utilitaire (disons Predicate), j'ai ajouté une méthode select avec une option pour la valeur par défaut lorsque le prédicat ne retourne pas la valeur attendue, ainsi qu'une propriété statique pour les paramètres à utiliser dans le nouveau IPredicate.
L'exemple suivant recherche les objets manquants entre les collections:
L'exemple suivant recherche une instance dans une collection et retourne le premier élément de la collection comme valeur par défaut lorsque l'instance est introuvable:
MISE À JOUR (après la sortie de Java 8):
Cela fait plusieurs années que j'ai (Alan) posté pour la première fois cette réponse, et je n'arrive toujours pas à croire que je collecte des points SO pour cette réponse. En tout cas, maintenant que Java 8 a introduit des fermetures au langage, ma réponse serait maintenant considérablement différente et plus simple. Avec Java 8, il n'est pas nécessaire d'avoir une classe d'utilitaire statique distincte. Donc, si vous voulez trouver le 1er élément qui correspond à votre prédicat.
Le 8 API pour JDK optionals a la capacité de
get()
,isPresent()
,orElse(defaultUser)
,orElseGet(userSupplier)
etorElseThrow(exceptionSupplier)
, ainsi que d' autres fonctions « monades » tels quemap
,flatMap
etfilter
.Si vous souhaitez simplement collecter tous les utilisateurs qui correspondent au prédicat, utilisez la
Collectors
pour terminer le flux dans la collection souhaitée.Voir ici pour plus d'exemples sur le fonctionnement des flux Java 8.
la source
val authorized = for (user <- users if user.isAuthorized) yield user
Utilisez CollectionUtils.filter (Collection, Predicate) , d'Apache Commons.
la source
La "meilleure" façon est une demande trop large. Est-ce "le plus court"? "Le plus rapide"? "Lisible"? Filtrer en place ou dans une autre collection?
La manière la plus simple (mais pas la plus lisible) est de l'itérer et d'utiliser la méthode Iterator.remove ():
Maintenant, pour le rendre plus lisible, vous pouvez l'envelopper dans une méthode utilitaire. Ensuite, inventez une interface IPredicate, créez une implémentation anonyme de cette interface et faites quelque chose comme:
où filterInPlace () itère la collection et appelle Predicate.keepIt () pour savoir si l'instance doit être conservée dans la collection.
Je ne vois pas vraiment de justification pour faire appel à une bibliothèque tierce uniquement pour cette tâche.
la source
stream()
fonctionnalité, mais tout le monde ne peut pas jouer avec les nouveaux jouets: PEnvisagez les collections Google pour un cadre de collections mis à jour qui prend en charge les génériques.
MISE À JOUR : La bibliothèque de collections Google est désormais obsolète. Vous devez utiliser la dernière version de Guava à la place. Il possède toujours les mêmes extensions du cadre des collections, y compris un mécanisme de filtrage basé sur un prédicat.
la source
Attendez Java 8:
la source
personList.removeIf(p -> p.age < 30);
Moins verbeux. De plus, j'ai entendu parler de commencer à implémenter des API qui acceptent et renvoient desStream
s plutôt que desCollection
s car lesStream
s sont très utiles et rapides mais aller vers / depuis eux est lent.Depuis la première version de Java 8, vous pouvez essayer quelque chose comme:
Par exemple, si vous aviez une liste d'entiers et que vous vouliez filtrer les nombres> 10, puis les imprimer sur la console, vous pourriez faire quelque chose comme:
la source
Je vais lancer RxJava dans le ring, qui est également disponible sur Android . RxJava n'est peut-être pas toujours la meilleure option, mais il vous donnera plus de flexibilité si vous souhaitez ajouter plus de transformations sur votre collection ou gérer les erreurs lors du filtrage.
Production:
Plus de détails sur RxJava
filter
peuvent être trouvés ici .la source
La mise en place:
L'usage:
la source
Que diriez-vous de Java simple et direct
Simple, lisible et facile (et fonctionne sous Android!) Mais si vous utilisez Java 8, vous pouvez le faire en une seule ligne:
Notez que toList () est importé statiquement
la source
Voulez-vous vraiment filtrer la collection elle-même plutôt qu'un itérateur?
voir org.apache.commons.collections.iterators.FilterIterator
ou en utilisant la version 4 d'apache commons org.apache.commons.collections4.iterators.FilterIterator
la source
Voyons comment filtrer une liste JDK intégrée et une liste MutableList à l' aide des collections Eclipse .
Si vous vouliez filtrer les nombres inférieurs à 3, vous vous attendriez aux sorties suivantes.
Voici comment filtrer en utilisant un lambda Java 8 comme
Predicate
.Voici comment filtrer en utilisant une classe interne anonyme comme
Predicate
.Voici quelques alternatives au filtrage des listes JDK et des collections Eclipse MutableLists à l'aide de la fabrique Predicates .
Voici une version qui n'alloue pas d'objet au prédicat, en utilisant la fabrique Predicates2 à la place avec la
selectWith
méthode qui prend aPredicate2
.Parfois, vous souhaitez filtrer sur une condition négative. Il existe une méthode spéciale dans les collections Eclipse pour celle appelée
reject
.La méthode
partition
renverra deux collections, contenant les éléments sélectionnés et rejetés par lePredicate
.Remarque: je suis un committer pour les collections Eclipse.
la source
removeIf
sur une liste ou un ensemble de primitives?Avec le ForEach DSL, vous pouvez écrire
Étant donné une collection de [The, quick, brown, fox, jumps, over, the, lazy, dog] cela se traduit par [quick, brown, jumps, over, lazy], c'est-à-dire toutes les chaînes de plus de trois caractères.
Tous les styles d'itération pris en charge par le ForEach DSL sont
AllSatisfy
AnySatisfy
Collect
Counnt
CutPieces
Detect
GroupedBy
IndexOf
InjectInto
Reject
Select
Pour plus de détails, veuillez vous référer à https://www.iam.unibe.ch/scg/svn_repos/Sources/ForEach
la source
La méthode Collections2.filter (Collection, Predicate) de la bibliothèque Google de Guava fait exactement ce que vous recherchez.
la source
Depuis java 9
Collectors.filtering
est activé:Le filtrage devrait donc être:
Exemple:
la source
Ceci, combiné au manque de fermetures réelles, est mon plus gros reproche pour Java. Honnêtement, la plupart des méthodes mentionnées ci-dessus sont assez faciles à lire et vraiment efficaces; cependant, après avoir passé du temps avec .Net, Erlang, etc ... la compréhension de la liste intégrée au niveau de la langue rend tout tellement plus propre. Sans ajouts au niveau du langage, Java ne peut tout simplement pas être aussi propre que de nombreux autres langages dans ce domaine.
Si les performances sont une préoccupation majeure, les collections Google sont le chemin à parcourir (ou écrivez votre propre utilitaire de prédicat simple). La syntaxe Lambdaj est plus lisible pour certaines personnes, mais elle n'est pas aussi efficace.
Et puis il y a une bibliothèque que j'ai écrite. J'ignorerai toutes les questions concernant son efficacité (oui, c'est si mauvais) ...... Oui, je sais que c'est clairement basé sur la réflexion, et non je ne l'utilise pas vraiment, mais ça marche:
OU
la source
JFilter http://code.google.com/p/jfilter/ est le mieux adapté à vos besoins.
JFilter est une bibliothèque open source simple et hautes performances pour interroger la collection de beans Java.
Principales caractéristiques
la source
J'ai écrit une classe Iterable étendue qui prend en charge l'application d'algorithmes fonctionnels sans copier le contenu de la collection.
Usage:
Le code ci-dessus s'exécutera réellement
la source
Utilisez Collection Query Engine (CQEngine) . C'est de loin le moyen le plus rapide de le faire.
Voir aussi: Comment interroger des collections d'objets en Java (critères / de type SQL)?
la source
Quelques très bonnes réponses ici. Moi, je voudrais garder les minces aussi simples et lisibles que possible:
la source
La solution simple pré-Java8:
Malheureusement, cette solution n'est pas entièrement générique, produisant une liste plutôt que le type de la collection donnée. De plus, apporter des bibliothèques ou écrire des fonctions qui enveloppent ce code me semble exagéré à moins que la condition ne soit complexe, mais vous pouvez alors écrire une fonction pour la condition.
la source
https://code.google.com/p/joquery/
Prend en charge différentes possibilités,
Étant donné la collection,
de type,
Filtre
Java 7
Java 8
Aussi,
Tri (également disponible pour Java 7)
Groupement (également disponible pour Java 7)
Jointures (également disponible pour Java 7)
Donné,
Peut être rejoint comme,
Expressions
la source
Ma réponse s'appuie sur celle de Kevin Wong, ici en tant que doublure utilisant à
CollectionUtils
partir du printemps et une expression lambda Java 8 .C'est aussi concis et lisible que n'importe quelle alternative que j'ai vue (sans utiliser de bibliothèques basées sur l'aspect)
Spring CollectionUtils est disponible à partir de la version Spring 4.0.2.RELEASE, et n'oubliez pas que vous avez besoin du JDK 1.8 et du niveau de langue 8+.
la source
En utilisant
java 8
, spécifiquementlambda expression
, vous pouvez le faire simplement comme dans l'exemple ci-dessous:où pour chaque collection
product
intérieuremyProducts
, siprod.price>10
, puis ajoutez ce produit à la nouvelle liste filtrée.la source
J'avais besoin de filtrer une liste en fonction des valeurs déjà présentes dans la liste. Par exemple, supprimez toutes les valeurs suivantes inférieures à la valeur actuelle. {2 5 3 4 7 5} -> {2 5 7}. Ou par exemple pour supprimer tous les doublons {3 5 4 2 3 5 6} -> {3 5 4 2 6}.
Ce sera utilisé comme ça.
la source
Avec la goyave:
la source
Dans Java 8, vous pouvez utiliser directement cette méthode de filtrage, puis le faire.
la source