290 votes

Java List.contains(Objet dont la valeur du champ est égale à x)

Je veux vérifier si un List contient un objet qui a un champ avec une certaine valeur. Je pourrais utiliser une boucle pour vérifier, mais j'étais curieux de savoir s'il y avait quelque chose de plus efficace.

Quelque chose comme ;

if(list.contains(new Object().setName("John"))){
    //Do some stuff
}

Je sais que le code ci-dessus ne fait rien, c'est juste pour démontrer grossièrement ce que j'essaie d'obtenir.

Aussi, juste pour clarifier, la raison pour laquelle je ne veux pas utiliser une simple boucle est que ce code va actuellement aller dans une boucle qui est dans une boucle qui est dans une boucle. Pour des raisons de lisibilité, je ne veux pas continuer à ajouter des boucles à ces boucles. Je me suis donc demandé s'il existait des alternatives simples (ou presque).

19voto

Debojit Saikia Points 8634

Recherche binaire

Vous pouvez utiliser Collections.binarySearch pour rechercher un élément de votre liste (en supposant que la liste est triée) :

Collections.binarySearch(list, new YourObject("a1", "b",
                "c"), new Comparator<YourObject>() {

            @Override
            public int compare(YourObject o1, YourObject o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });

qui renverra un nombre négatif si l'objet n'est pas présent dans la collection ou sinon il renverra la valeur index de l'objet. Vous pouvez ainsi rechercher des objets avec différentes stratégies de recherche.

8voto

Carte

Vous pourriez créer un Hashmap<String, Object> en utilisant une des valeurs comme clé, puis en regardant si yourHashMap.keySet().contains(yourValue) retourne vrai.

6voto

Craig P. Motlin Points 11814

Collections Eclipse

Si vous utilisez Collections Eclipse vous pouvez utiliser l'option anySatisfy() méthode. Soit vous adaptez votre List dans un ListAdapter ou changez votre List en un ListIterable si possible.

ListIterable<MyObject> list = ...;

boolean result =
    list.anySatisfy(myObject -> myObject.getName().equals("John"));

Si vous effectuez fréquemment des opérations de ce type, il est préférable d'extraire une méthode qui répond à la question de savoir si le type possède l'attribut.

public class MyObject
{
    private final String name;

    public MyObject(String name)
    {
        this.name = name;
    }

    public boolean named(String name)
    {
        return Objects.equals(this.name, name);
    }
}

Vous pouvez utiliser la forme alternative anySatisfyWith() ainsi qu'une référence de méthode.

boolean result = list.anySatisfyWith(MyObject::named, "John");

Si vous ne pouvez pas changer votre List en un ListIterable voici comment vous utiliseriez ListAdapter .

boolean result = 
    ListAdapter.adapt(list).anySatisfyWith(MyObject::named, "John");

Note : Je suis un committer pour Eclipse ollections.

5voto

user902383 Points 3242

Predicate

Si vous n'utilisez pas Java 8, ou une bibliothèque qui vous donne plus de fonctionnalités pour traiter les collections, vous pourriez mettre en œuvre quelque chose qui peut être plus réutilisable que votre solution.

interface Predicate<T>{
        boolean contains(T item);
    }

    static class CollectionUtil{

        public static <T> T find(final Collection<T> collection,final  Predicate<T> predicate){
            for (T item : collection){
                if (predicate.contains(item)){
                    return item;
                }
            }
            return null;
        }
    // and many more methods to deal with collection    
    }

J'utilise quelque chose comme ça, j'ai une interface de prédicat, et je passe son implémentation à ma classe util.

Quel est l'avantage de faire cela à ma façon ? vous avez une méthode qui traite de la recherche dans n'importe quel type de collection. et vous n'avez pas besoin de créer des méthodes séparées si vous voulez rechercher par un champ différent. tout ce que vous devez faire est de fournir un prédicat différent qui peut être détruit dès qu'il n'est plus utile.

Si vous voulez l'utiliser, il suffit d'appeler la méthode et de définir votre prédicat.

CollectionUtil.find(list, new Predicate<MyObject>{
    public boolean contains(T item){
        return "John".equals(item.getName());
     }
});

4voto

Phan Van Linh Points 16963

Voici une solution utilisant Goyave

private boolean checkUserListContainName(List<User> userList, final String targetName){

    return FluentIterable.from(userList).anyMatch(new Predicate<User>() {
        @Override
        public boolean apply(@Nullable User input) {
            return input.getName().equals(targetName);
        }
    });
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X