web-dev-qa-db-fra.com

Comment déterminer si un tableau contient une valeur particulière en Java?

J'ai un String[] avec des valeurs telles que:

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

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

2151
Mike Sickler
Arrays.asList(yourArray).contains(yourValue)

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


Depuis Java-8 , vous pouvez maintenant utiliser des flux.

String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);

Pour vérifier si un tableau de int, double ou long contient une valeur, utilisez IntStream, DoubleStream ou LongStream.

Exemple

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

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

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

Ceci est une statique modifiable que FindBugs vous dira est très méchant. Il devrait être privé:

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

(Notez que vous pouvez réellement supprimer le bit new String[];.)

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 paranoïaques, comme moi, peuvent se sentir plus à l'aise si cela était enveloppé dans Collections.unmodifiableSet - cela pourrait même être rendu public.)

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

VALUES.contains(s)

O (1).

Mise à jour: Depuis Java SE 9, nous avons Set.of.

private static final Set<String> VALUES = Set.of(
    "AB","BC","CD","AE"
);

Les type correct, immuable, O (1) et concis. Magnifique.

(Pour en savoir un peu plus sur la marque, il était prévisible que les types de collection immuables ne sont pas immuables dans l'API de collections et que la syntaxe est encore beaucoup trop détaillée, à mon goût.)

342

Vous pouvez utiliser ArrayUtils.contains de Apache Commons Lang

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

Notez que cette méthode retourne 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.
}
193
Intracer

Il suffit simplement de le mettre en œuvre à 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:

La condition v != null est constante dans la méthode. Il évalue toujours la même valeur booléenne lors de l'appel de la méthode. Donc, si l'entrée array est grande, il est plus efficace d'évaluer cette condition une seule fois, et nous pouvons utiliser une condition simplifiée/plus rapide dans la boucle for en fonction du résultat. La méthode améliorée contains():

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;
}
154
icza

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

Si le tableau est trié, vous pouvez effectuer une recherche binaire, il y en a une dans la classe Arrays .

En règle générale, si vous allez effectuer beaucoup de vérifications d'adhésion, vous pouvez vouloir tout stocker dans un ensemble, pas dans un tableau.

70
Uri

Quatre manières différentes de vérifier si un tableau contient une valeur

1) Utiliser la liste:

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

2) en utilisant l'ensemble:

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) Utilisation de Arrays.binarySearch ():

Le code ci-dessous est faux, il est listé ici pour être complet. binarySearch () peut UNIQUEMENT être utilisé sur des tableaux triés. Vous trouverez le résultat est bizarre ci-dessous. C'est la meilleure option lorsque 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
68

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

Lors de l'utilisation d'une taille de tableau de 10K, les résultats sont les suivants:

 Sort & Search: 15 
 Recherche binaire: 0 
 AsList.contains: 0 

Lors de l'utilisation d'un tableau de 100K, les résultats sont les suivants:

 Sort & Search: 156 
 Recherche binaire: 0 
 AsList.contains: 32 

Donc, si le tableau est créé dans un ordre trié, la recherche binaire est la plus rapide, sinon la asList().contains serait la solution. Si vous avez beaucoup de recherches, alors il peut être intéressant de trier le tableau pour pouvoir utiliser la recherche binaire. Tout dépend de votre application.

Je pense que ce sont les résultats auxquels la plupart des gens s'attendent. 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));
    }
}
48
camickr

Avec Java 8, vous pouvez créer un flux et vérifier si une entrée du flux correspond à "s":

String[] values = {"AB","BC","CD","AE"};
boolean sInArray = Arrays.stream(values).anyMatch("s"::equals);

Ou comme méthode générique:

public static <T> boolean arrayContains(T[] array, T value) {
    return Arrays.stream(array).anyMatch(value::equals);
}
34
assylias

Au lieu d'utiliser également la syntaxe d'initialisation rapide du tableau, vous pouvez l'initialiser immédiatement sous forme de liste de manière similaire à l'aide de la méthode Arrays.asList, par exemple:

public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");

Ensuite, vous pouvez faire (comme ci-dessus):

STRINGS.contains("the string you want to find");
34
Mark Rhodes

Vous pouvez utiliser le classe Arrays pour effectuer une recherche binaire de la valeur. Si votre tableau n'est pas trié, vous devrez utiliser les fonctions de tri de la même classe pour trier le tableau, puis effectuez une recherche.

26
Thomas Owens

ObStupidAnswer (mais je pense qu'il y a une leçon quelque part):

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}
18

En fait, si vous utilisez HashSet <String> comme le propose Tom Hawtin, vous n'avez pas à vous soucier du tri et votre vitesse est identique à celle de la recherche binaire sur un tableau pré-trié, probablement même plus rapide.

Tout dépend de la manière dont votre code est configuré, évidemment, mais dans l'ordre où je me trouve, l'ordre serait:

Sur un non trié tableau:

  1. HashSet
  2. asList
  3. trier et binaire

Sur un tableau trié:

  1. HashSet
  2. Binaire
  3. asList

Alors de toute façon, HashSet pour la victoire.

13
not

Si vous avez la bibliothèque de collections Google, la réponse de Tom peut être simplifiée beaucoup en utilisant ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html).

Cela supprime vraiment beaucoup d'encombrement de l'initialisation proposée

private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");
11
jhodges

Une solution possible:

import Java.util.Arrays;
import Java.util.List;

public class ArrayContainsElement {
  public static final List<String> VALUES = Arrays.asList("AB", "BC", "CD", "AE");

  public static void main(String args[]) {

      if (VALUES.contains("AB")) {
          System.out.println("Contains");
      } else {
          System.out.println("Not contains");
      }
  }
}
10
Christian Giménez

Les développeurs font souvent:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

Le code ci-dessus fonctionne, mais il n'est pas nécessaire de convertir une liste à définir en premier. La conversion d'une liste en un ensemble nécessite du temps supplémentaire. Cela peut être aussi simple que:

Arrays.asList(arr).contains(targetValue);

ou

   for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }

return false;

Le premier est plus lisible que le second.

8
Xar E Ahmer

Dans Java 8 utilisez Streams.

List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
7
Shineed Basheer

Le moyen le plus efficace consiste à utiliser une boucle simple.

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

Courtoisie à Programcreek

7
Ryan
  1. Pour les tableaux de longueur limitée, utilisez ce qui suit (comme indiqué par camickr ). Ceci est lent pour les contrôles répétés, en particulier pour les tableaux plus longs (recherche linéaire).

     Arrays.asList(...).contains(...)
    
  2. Pour des performances rapides si vous vérifiez à plusieurs reprises par rapport à un ensemble d'éléments plus volumineux

    • Un tableau est la mauvaise structure. Utilisez un TreeSet et ajoutez-y chaque élément. Il trie les éléments et utilise une méthode rapide exist() (recherche binaire).

    • Si les éléments implémentent Comparable & vous voulez que le TreeSet soit trié en conséquence:

      La méthode ElementClass.compareTo() doit être compatible avec ElementClass.equals(): voir les triades ne s'affichent pas pour combattre? (Java met un élément manquant)

      TreeSet myElements = new TreeSet();
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
      // *Alternatively*, if an array is forceably provided from other code:
      myElements.addAll(Arrays.asList(myArray));
      
    • Sinon, utilisez votre propre Comparator:

      class MyComparator implements Comparator<ElementClass> {
           int compareTo(ElementClass element1; ElementClass element2) {
                // Your comparison of elements
                // Should be consistent with object equality
           }
      
           boolean equals(Object otherComparator) {
                // Your equality of comparators
           }
      }
      
      
      // construct TreeSet with the comparator
      TreeSet myElements = new TreeSet(new MyComparator());
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
    • Le gain: vérifier l'existence d'un élément:

      // Fast binary search through sorted elements (performance ~ log(size)):
      boolean containsElement = myElements.exists(someElement);
      
5
Glen Best

Essaye ça:

ArrayList<Integer> arrlist = new ArrayList<Integer>(8);

// use add() method to add elements in the list
arrlist.add(20);
arrlist.add(25);
arrlist.add(10);
arrlist.add(15);

boolean retval = arrlist.contains(10);
if (retval == true) {
    System.out.println("10 is contained in the list");
}
else {
    System.out.println("10 is not contained in the list");
}
4
Mr.G

Utilisez les éléments suivants (la méthode contains() est ArrayUtils.in() dans ce code):

ObjectUtils.Java

public class ObjectUtils{

    /**
     * A null safe method to detect if two objects are equal.
     * @param object1
     * @param object2
     * @return true if either both objects are null, or equal, else returns false.
     */
    public static boolean equals(Object object1, Object object2){
        return object1==null ? object2==null : object1.equals(object2);
    }

}

ArrayUtils.Java

public class ArrayUtils{

    /**
     * Find the index of of an object is in given array, starting from given inclusive index.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @param start  The index from where the search must start.
     * @return Index of the given object in the array if it is there, else -1.
     */
    public static <T> int indexOf(final T[] ts, final T t, int start){
        for(int i = start; i < ts.length; ++i)
            if(ObjectUtils.equals(ts[i], t))
                return i;
        return -1;
    }

    /**
     * Find the index of of an object is in given array, starting from 0;
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  indexOf(ts, t, 0)
     */
    public static <T> int indexOf(final T[] ts, final T t){
        return indexOf(ts, t, 0);
    }

    /**
     * Detect if the given object is in the given array.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  If indexOf(ts, t) is greater than -1.
     */
    public static <T> boolean in(final T[] ts, final T t){
        return indexOf(ts, t) > -1 ;
    }

}

Comme vous pouvez le constater dans le code ci-dessus, il existe d'autres méthodes utilitaires ObjectUtils.equals() et ArrayUtils.indexOf() qui étaient également utilisées à d'autres endroits.

4
Abhishek Oza

Arrays.asList () -> puis l'appel de la méthode contains () fonctionnera toujours, mais un algorithme de recherche est bien meilleur car vous n'avez pas besoin de créer un wrapper de liste léger autour du tableau, ce que fait Arrays.asList () .

public boolean findString(String[] strings, String desired){
   for (String str : strings){
       if (desired.equals(str)) {
           return true;
       }
   }
   return false; //if we get here… there is no desired String, return false.
}
3
WIll

Si vous ne voulez pas qu'il soit sensible à la casse

Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
3
Akhil babu K

Utilisez Array.BinarySearch(array,obj) pour trouver ou non l'objet donné dans un tableau.

Exemple:

if (Array.BinarySearch(str, i) > -1)` → true --exists

faux - n'existe pas

3
Avenger

Vérifie ça

String[] VALUES = new String[] {"AB","BC","CD","AE"};
String s;

for(int i=0; i< VALUES.length ; i++)
{
    if ( VALUES[i].equals(s) )
    { 
        // do your stuff
    } 
    else{    
        //do your stuff
    }
}
3
SubbaRao Boddu

Créez un booléen initialement défini sur false. Exécutez une boucle pour vérifier chaque valeur du tableau et comparez-la à la valeur que vous vérifiez. Si vous obtenez une correspondance, définissez boolean sur true et arrêtez la mise en boucle. Ensuite, affirmez que le booléen est vrai.

0
mandy1339