¿Cómo puedo determinar si una matriz contiene un valor particular en Java?
Tengo un String[]
con valores como este:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Dado String s
, ¿existe una buena manera de probar si VALUES
contiene s
?
Arrays.asList(yourArray).contains(yourValue)
Advertencia: esto no funciona para matrices de primitivas (ver los comentarios).
Desdejava-8ahora puedes usar Streams.
String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);
Para comprobar si una matriz de int
, double
o long
contiene un valor, utilice IntStream
, DoubleStream
o LongStream
respectivamente.
Ejemplo
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
Actualización concisa para Java SE 9
Las matrices de referencia son malas. Para este caso buscamos un conjunto. Desde Java SE 9 tenemos Set.of
.
private static final Set<String> VALUES = Set.of(
"AB","BC","CD","AE"
);
"Dada la cadena s, ¿hay una buena manera de probar si VALUES contiene s?"
VALUES.contains(s)
O(1).
El tipo correcto , inmutable , O(1) y conciso . Hermoso.*
Detalles de la respuesta original
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 traviesa. No modifique la estática y no permita que otro código lo haga también. Como mínimo absoluto, el campo debe ser privado:
private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
(Tenga en cuenta que, en realidad, puede soltar la new String[];
broca).
Las matrices de referencia siguen siendo malas y queremos un conjunto:
private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
new String[] {"AB","BC","CD","AE"}
));
(Las personas paranoicas, como yo, pueden sentirse más tranquilas si esto estuviera incluido Collections.unmodifiableSet
; entonces incluso podría hacerse público).
(* Para ser un poco más centrado en la marca, como era de esperar, a la API de colecciones todavía le faltan tipos de colecciones inmutables y la sintaxis sigue siendo demasiado detallada, para mi gusto).
Puedes usar ArrayUtils.contains
desde Apache Commons Lang
public static boolean contains(Object[] array, Object objectToFind)
Tenga en cuenta que este método devuelve false
si la matriz pasada 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.
}
Simplemente impleméntelo a mano:
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;
}
Mejora:
La v != null
condición es constante dentro del método. Siempre se evalúa con el mismo valor booleano durante la llamada al método. Entonces, si la entrada array
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 for
ciclo según el resultado. El método mejorado 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;
}
Cuatro formas diferentes de comprobar si una matriz contiene un valor
Usando
List
:public static boolean useList(String[] arr, String targetValue) { return Arrays.asList(arr).contains(targetValue); }
Usando
Set
:public static boolean useSet(String[] arr, String targetValue) { Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue); }
Usando un bucle simple:
public static boolean useLoop(String[] arr, String targetValue) { for (String s: arr) { if (s.equals(targetValue)) return true; } return false; }
Usando
Arrays.binarySearch()
:El siguiente código es incorrecto; se incluye aquí para que esté completo.
binarySearch()
SÓLO se puede utilizar en matrices ordenadas. Encontrarás que el resultado es extraño a continuación. Esta es la mejor opción cuando se ordena la matriz.public static boolean binarySearch(String[] arr, String targetValue) { return Arrays.binarySearch(arr, targetValue) >= 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
Si la matriz no está ordenada, tendrá que iterar sobre todo y hacer una llamada a iguales en cada uno.
Si la matriz está ordenada, puedes hacer una búsqueda binaria, hay una en la clase Arrays .
En términos generales, si va a realizar muchas comprobaciones de membresía, es posible que desee almacenar todo en un Conjunto, no en una matriz.