Question Comment puis-je tester si un tableau contient une certaine valeur?


j'ai un String[] avec des valeurs comme:

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

Donné String s, existe-t-il un bon moyen de tester si VALUES contient s?


1850
2017-07-15 00:03


origine


Réponses:


Arrays.asList(yourArray).contains(yourValue)

Attention: cela ne fonctionne pas pour les tableaux de primitives (voir les commentaires).


Depuis

Vous pouvez maintenant utiliser un Stream pour vérifier si un tableau de int, double ou long contient une valeur (en utilisant respectivement un IntStream, DoubleStream ou LongStream)

Exemple

int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);

2423
2017-07-15 00:04



Juste pour effacer le code pour commencer. Nous avons (corrigé):

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

C'est un static mutable que FindBugs vous dira est très vilain. Cela devrait être privé:

private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

(Remarque, vous pouvez réellement laisser tomber le new String[]; bit.)

Donc, les tableaux de référence sont mauvais, et en particulier ici nous voulons un ensemble:

private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
     new String[] {"AB","BC","CD","AE"}
));

(Les personnes paranoïaques, comme moi, peuvent se sentir plus à l'aise si cela était enveloppé Collections.unmodifiableSet - Il pourrait même être rendu public.)

"Étant donné String s, existe-t-il un bon moyen de tester si VALUES contient s?"

VALUES.contains(s)

O (1).


309
2017-07-15 01:13



Vous pouvez utiliser ArrayUtils.contains de Apache Commons Lang

public static boolean contains(Object[] array, Object objectToFind)

Notez que cette méthode renvoie false si le tableau transmis est null.

Il existe également des méthodes disponibles pour les tableaux primitifs de toutes sortes.

Exemple:

String[] fieldsToInclude = { "id", "name", "location" };

if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
    // Do some stuff.
}

171
2018-05-31 13:17



Je suis surpris que personne ne suggère de simplement l'appliquer à la main:

public static <T> boolean contains(final T[] array, final T v) {
    for (final T e : array)
        if (e == v || v != null && v.equals(e))
            return true;

    return false;
}

Amélioration:

le v != null condition est constante dans la méthode, elle est toujours évaluée à la même valeur booléenne lors de l'appel de la méthode. Donc, si l'entrée array est grand, il est plus efficace d'évaluer cette condition qu'une seule fois et nous pouvons utiliser une condition simplifiée / plus rapide à l'intérieur du for boucle en fonction du résultat. L'amélioration contains() méthode:

public static <T> boolean contains2(final T[] array, final T v) {
    if (v == null) {
        for (final T e : array)
            if (e == null)
                return true;
    } else {
        for (final T e : array)
            if (e == v || v.equals(e))
                return true;
    }

    return false;
}

142
2017-09-28 07:45



Si le tableau n'est pas trié, vous devrez parcourir tout et faire un appel à égal sur chacun.

Si le tableau est trié, vous pouvez faire une recherche binaire, il y en a une dans le Tableaux classe.

En règle générale, si vous effectuez beaucoup de contrôles d'adhésion, vous pouvez stocker tout dans un ensemble, et non dans un tableau.


65
2017-07-15 00:05



Quatre façons différentes de vérifier si un tableau contient une valeur

1) En utilisant la liste:

public static boolean useList(String[] arr, String targetValue) {
    return Arrays.asList(arr).contains(targetValue);
}

2) En utilisant Set:

public static boolean useSet(String[] arr, String targetValue) {
    Set<String> set = new HashSet<String>(Arrays.asList(arr));
    return set.contains(targetValue);
}

3) En utilisant une simple boucle:

public static boolean useLoop(String[] arr, String targetValue) {
    for (String s: arr) {
        if (s.equals(targetValue))
            return true;
    }
    return false;
}

4) En utilisant Arrays.binarySearch ():

Le code ci-dessous est faux, il est listé ici pour être complet. binarySearch () ne peut être utilisé que sur des tableaux triés. Vous trouverez le résultat est bizarre ci-dessous. C'est la meilleure option quand le tableau est trié.

public static boolean binarySearch(String[] arr, String targetValue) {  
            int a = Arrays.binarySearch(arr, targetValue);
            return a > 0;
        }

Exemple rapide:

String testValue="test";
String newValueNotInList="newValue";
String[] valueArray = { "this", "is", "java" , "test" };
Arrays.asList(valueArray).contains(testValue); // returns true
Arrays.asList(valueArray).contains(newValueNotInList); // returns false

59
2018-05-07 19:14



Pour ce que ça vaut, j'ai fait un test comparant les 3 suggestions pour la vitesse. J'ai généré des entiers aléatoires, les ai convertis en une chaîne et les ai ajoutés à un tableau. J'ai ensuite recherché le nombre / chaîne le plus élevé possible, ce qui serait le pire des cas pour asList (). Contains ().

Lorsque vous utilisez une taille de tableau de 10 Ko, les résultats sont les suivants:

Trier & Chercher: 15
Recherche binaire: 0
asList.contains: 0

Lorsque vous utilisez un tableau de 100 Ko, les résultats sont les suivants:

Trier & Chercher: 156
Recherche binaire: 0
asList.contains: 32

Donc, si le tableau est créé dans l'ordre trié, la recherche binaire est la plus rapide, sinon le fichier asList (). Serait le chemin à parcourir. Si vous avez plusieurs recherches, il peut être utile de trier le tableau pour pouvoir utiliser la recherche binaire. Tout dépend de votre application.

Je pense que ce sont les résultats les plus attendus. Voici le code de test:

import java.util.*;

public class Test
{
    public static void main(String args[])
    {
        long start = 0;
        int size = 100000;
        String[] strings = new String[size];
        Random random = new Random();


        for (int i = 0; i < size; i++)
            strings[i] = "" + random.nextInt( size );

        start = System.currentTimeMillis();
        Arrays.sort(strings);
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Sort & Search : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Search        : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.asList(strings).contains( "" + (size - 1) ));
        System.out.println("Contains      : " + (System.currentTimeMillis() - start));
    }
}

46
2017-07-15 01:28