¿Cómo puedo probar si una matriz contiene un cierto valor?

Tengo un String[] con valores como ese:

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

Dado String s , ¿hay una buena forma de probar si VALUES contiene s ?

 Arrays.asList(yourArray).contains(yourValue) 

Advertencia: esto no funciona para arreglos de primitivos (ver los comentarios).


Desde java-8

Ahora puede usar un Stream para verificar si una matriz de int , double o long contiene un valor (utilizando respectivamente un IntStream , DoubleStream o LongStream )

Ejemplo

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

Solo para borrar el código para empezar. Tenemos (corregido):

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

Esta es una estática mutable que FindBugs te dirá que es muy travieso. Debe ser privado:

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

(Tenga en cuenta que puede soltar el new String[]; bit)

Entonces, las matrices de referencia son malas, y en particular aquí queremos un conjunto:

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

(Las personas paranoicas, como yo, pueden sentirse más a gusto si esto estuviera incluido en Collections.unmodifiableSet , incluso podría hacerse público).

“Given String s, ¿hay una buena forma de probar si VALUES contiene s?”

 VALUES.contains(s) 

O (1).

Puede usar ArrayUtils.contains de Apache Commons Lang

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

Tenga en cuenta que este método devuelve false si el conjunto pasado es null .

También hay métodos disponibles para matrices primitivas de todo tipo.

Ejemplo:

 String[] fieldsToInclude = { "id", "name", "location" }; if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) { // Do some stuff. } 

Me sorprende que nadie sugiriera simplemente implementarlo a mano:

 public static  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; } 

Mejora:

La condición v != null es constante dentro del método, siempre se evalúa con el mismo valor booleano durante la llamada al método. Entonces, si la array entrada es grande, es más eficiente evaluar esta condición solo una vez y podemos usar una condición simplificada / más rápida dentro del ciclo for basado en el resultado. El método de contains() mejorado:

 public static  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; } 

Si la matriz no está ordenada, tendrá que iterar sobre todo y hacer una llamada a iguales en cada una.

Si la matriz está ordenada, puede hacer una búsqueda binaria, hay una en la clase Arrays .

En términos generales, si va a hacer muchas comprobaciones de membresía, es posible que desee almacenar todo en un conjunto, no en un conjunto.

Cuatro formas diferentes de verificar si una matriz contiene un valor

1) Usando la lista:

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

2) Usando Set:

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

3) Usando un bucle simple:

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

4) Usando Arrays.binarySearch ():

El código siguiente es incorrecto, se detalla aquí para completarlo. binarySearch () SOLAMENTE se puede usar en arreglos ordenados. Encontrará que el resultado es extraño a continuación. Esta es la mejor opción cuando se ordena el conjunto.

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

Ejemplo rápido:

 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 

Por lo que vale, realicé una prueba comparando las 3 sugerencias de velocidad. Genere enteros aleatorios, los convertí en una cadena y los agregué a una matriz. Luego busqué el mayor número / cadena posible, que sería el peor de los casos para el asList (). Contains ().

Cuando se usa un tamaño de matriz de 10K, los resultados son:

 Ordenar y Buscar: 15
 Búsqueda binaria: 0
 asList.contains: 0

Cuando se usa una matriz de 100 K los resultados son:

 Ordenar y Buscar: 156
 Búsqueda binaria: 0
 asList.contains: 32

Entonces, si la matriz se crea en orden ordenado, la búsqueda binaria es la más rápida, de lo contrario, el asList (). Contiene sería el camino a seguir. Si tiene muchas búsquedas, puede valer la pena ordenar la matriz para que pueda usar la búsqueda binaria. Todo depende de tu aplicación.

Creo que esos son los resultados que la mayoría de la gente esperaría. Aquí está el código de prueba:

 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)); } } 

En lugar de utilizar la syntax de inicialización de matriz rápida, puede inicializarla como una lista directamente de manera similar utilizando el método Array.asList, por ejemplo:

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

Entonces puede hacer (como arriba): STRINGS.contains("the string you want to find");

Con Java 8 puede crear una secuencia y verificar si alguna entrada en la secuencia coincide con "s" :

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

O como un método genérico:

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

Puede usar la clase Arrays para realizar una búsqueda binaria del valor. Si su matriz no está ordenada, tendrá que usar las funciones de clasificación en la misma clase para ordenar la matriz, y luego buscar a través de ella.

ObStupidAnswer (pero creo que hay una lección aquí en algún lado):

 enum Values { AB, BC, CD, AE } try { Values.valueOf(s); return true; } catch (IllegalArgumentException exc) { return false; } 

En realidad, si usa HashSet como propuso Tom Hawtin, no necesita preocuparse por la clasificación y su velocidad es la misma que con la búsqueda binaria en una matriz predefinida, probablemente incluso más rápido.

Todo depende de cómo esté configurado su código, obviamente, pero desde donde estoy, el orden sería:

En una matriz sin clasificar:

  1. HashSet
  2. asList
  3. ordenar y binario

En una matriz ordenada:

  1. HashSet
  2. Binario
  3. asList

Entonces, de cualquier manera, HashSet ftw

Si tiene la biblioteca de colecciones de google, la respuesta de Tom se puede simplificar mucho usando ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html)

Esto realmente elimina un montón de desorden de la inicialización propuesta

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

En Java 8 usa Streams.

 List myList = Arrays.asList("a1", "a2", "b1", "c2", "c1"); myList .stream() .filter(s -> s.startsWith("c")) .map(String::toUpperCase) .sorted() .forEach(System.out::println); 

Una posible solución:

 import java.util.Arrays; import java.util.List; public class ArrayContainsElement { public static final List 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"); } } } 

Los desarrolladores a menudo hacen:

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

El código anterior funciona, pero no es necesario convertir una lista para establecer primero. La conversión de una lista a un conjunto requiere tiempo adicional. Puede ser tan simple como:

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

o

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

El primero es más legible que el segundo.

Usar un bucle simple es la forma más eficiente de hacerlo.

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

Cortesía de Programcreek

  1. Para matrices de longitud limitada, use lo siguiente (dado por Camickr ). Esto es lento para comprobaciones repetidas, especialmente para arreglos más largos (búsqueda lineal).

      Arrays.asList(...).contains(...) 
  2. Para un rendimiento rápido si comprueba repetidamente contra un conjunto más grande de elementos

    • Una matriz es la estructura incorrecta. Use un TreeSet y agregue cada elemento a él. Clasifica los elementos y tiene un método rápido de exist() (búsqueda binaria).

    • Si los elementos implementan Comparable y quieres que TreeSet consecuencia:

      ElementClass.compareTo() método ElementClass.compareTo() debe ser compatible con ElementClass.equals() : ver Tríadas que no aparecen para luchar? (Java Set falta un elemento)

       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)); 
    • De lo contrario, use su propio Comparator :

       class MyComparator implements Comparator { 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); 
    • El pago: verificar la existencia de algún elemento:

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

Arrays.asList => luego aplicar el método contains () siempre funcionará, pero un algoritmo de búsqueda es mucho mejor ya que primero tienes que convertir el Array a una lista, luego llamar al método contains, duplicar el overhead, ver a qué me refiero ? Esto es porque es O (n) para crear la lista y O (n) para contiene para encontrar un elemento a través de la comprobación secuencial. ¿Por qué sufrir O (n) dos veces cuando una búsqueda lineal simple hace el trabajo una sola vez?

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

Use Array.BinarySearch(array,obj) para encontrar el objeto dado en la matriz o no. Ex:

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

falso –no existe

Estoy muy atrasado para unirme a esta discusión, pero dado que mi enfoque para resolver este problema, cuando lo enfrenté hace unos años, era un poco diferente de las otras respuestas ya publicadas aquí, estoy publicando esa solución que usaba en ese momento, aquí, en caso de que alguien lo encuentre útil: (El método contains() es ArrayUtils.in() en este código).

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  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  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  boolean in(final T[] ts, final T t){ return indexOf(ts, t) > -1 ; } } 

Como puede ver en el código anterior, existen otros métodos de utilidad ObjectUtils.equals() y ArrayUtils.indexOf() , que también se usaron en otros lugares.

Puede ser tan simple como:

 String[] VALUE = new String[] {"AB","BC","CD","AE"}; Arrays.asList(VALUE).contains(s); 

Mira esto

 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 } } 

Prueba esto:

 ArrayList arrlist = new ArrayList(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"); } 

Cree un valor booleano inicialmente establecido en falso. Ejecute un ciclo para verificar cada valor en la matriz y compare con el valor que está comprobando. Si alguna vez obtiene una coincidencia, establezca booleano en verdadero y detenga el bucle. Luego afirme que el booleano es verdadero.