Java, verificación simplificada si la matriz int contiene int


94

Básicamente, mi amigo ha estado diciendo que podría acortar mi código usando una forma diferente de verificar si una matriz int contiene un int, aunque no me dirá qué es: P.

Actual:

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}

También he probado esto, aunque siempre devuelve falso por alguna razón.

public boolean contains(final int[] array, final int key) {
    return Arrays.asList(array).contains(key);
}

¿Podría alguien ayudarme?

Gracias.


8
Su llamada Arrays.asList (...) toma un vararg, es decir, envolverá el número arbitrario de argumentos que podría pasar a eso en una Lista. En su caso, obtendrá una lista de matrices con un solo elemento, y esta lista obviamente no contiene el int.
sarcan

¿Tu comentario significa qué ahora?
sarcan

Hashsetrespuesta del mecanismo de nuevo juicio basado en cheque . Es la forma más rápida.
Amit Deshpande

No veo ningún sentido en acortar su código original ya que su argumento es una matriz primitiva y su código es muy claro y directo. ArrayListla implementación está haciendo lo mismo.
Genzer

No acortaría su código. (1) arraylist hace lo mismo que tú. (2) - lo más importante es que el código abreviado que usa Arrays.asList crea un nuevo objeto, lo que podría ser un problema dentro de algún código crítico para el rendimiento. El primer fragmento de código es lo mejor que puede hacer.
Martin Podval

Respuestas:


38

Aquí está la solución Java 8

public static boolean contains(final int[] arr, final int key) {
    return Arrays.stream(arr).anyMatch(i -> i == key);
}

63

Simplemente podría usar ArrayUtils.containsfrom Apache Commons Lang library.

public boolean contains(final int[] array, final int key) {     
    return ArrayUtils.contains(array, key);
}

1
Siempre que esté usando ArrayUtils, ¿hay alguna razón para no usar ArrayUtils.contains
mjohnsonengr

2
Sin motivo alguno :)
Reimeus

20
Vale la pena señalar que ArrayUtils.contains()es parte de la Apache Commons Langbiblioteca. A pesar de que es una gran biblioteca, probablemente no sea una buena idea agregar dependencia externa solo para verificar si la matriz contiene un elemento: D
Krzysiek

1
ArrayUtils es cosa del pasado. ¡Java 8+ y Guava tienen cosas increíbles!
TriCore

34

Es porque Arrays.asList(array)regresa List<int[]>. arrayEl argumento se trata como un valor que desea ajustar (obtiene una lista de matrices de entradas), no como vararg.

Nota que hace el trabajo con los tipos de objetos primitivos (no):

public boolean contains(final String[] array, final String key) {
    return Arrays.asList(array).contains(key);
}

o incluso:

public <T>  boolean contains(final T[] array, final T key) {
    return Arrays.asList(array).contains(key);
}

Pero no puede tener List<int>y el autoboxing no funciona aquí.


1
¿Por qué el autoboxing no funciona, es porque está declarado final?
subhashis

19

Guayaba ofrece métodos adicionales para tipos primitivos. Entre ellos, un método contiene que toma los mismos argumentos que el suyo.

public boolean contains(final int[] array, final int key) {
    return Ints.contains(array, key);
}

También puede importar estáticamente la versión de guayaba.

Ver la explicación de los primitivos de guayaba


18

De otra manera:

public boolean contains(final int[] array, final int key) {  
     Arrays.sort(array);  
     return Arrays.binarySearch(array, key) >= 0;  
}  

Esto modifica la matriz pasada. Tendría la opción de copiar la matriz y trabajar en la matriz original, es decir, int[] sorted = array.clone();
pero esto es solo un ejemplo de código corto. El tiempo de ejecución es O(NlogN)mientras tu camino esO(N)


30
Creo que me sorprendería si un containsmétodo modificara mi matriz.
Zong

@ZongLi: Este es solo un ejemplo para el OP. OP actualizado si somos quisquillosos
Cratylus

5
De javadoc de binarySearch (): "el valor de retorno será> = 0 si y solo si se encuentra la clave". por lo que Arrays.binarySearch (matriz, clave)> = 0 debe devolverse.
icza

Suplemento: El valor de retorno de binarySearch () es (- (punto de inserción) - 1) si la clave no está contenida, que probablemente puede ser un valor distinto de -1.
icza

Esto no puede ser -1si tiene la intención de ser verdad. "El punto de inserción se define como el punto en el que se insertaría la clave en la lista: el índice del primer elemento mayor que la clave, o list.size () si todos los elementos de la lista son menores que la clave especificada. ". Necesito decir >= 0.
Brian

17

Sé que es muy tarde, pero inténtalo en Integer[]lugar de hacerlo int[].


Esta es la solucion.
atheesh27

Voto a favor de la respuesta de trabajo, gracias Willy
ucMedia

1

Usos únicos

List<T> list=Arrays.asList(...)
list.contains(...)

2.use HashSet para considerar el rendimiento si lo usa más de una vez.

Set <T>set =new HashSet<T>(Arrays.asList(...));
set.contains(...)

1

Prueba esto:

public static void arrayContains(){
    int myArray[]={2,2,5,4,8};

    int length=myArray.length;

    int toFind = 5;
    boolean found = false;

    for(int i = 0; i < length; i++) {
        if(myArray[i]==toFind) {
            found=true;
        }
    }

    System.out.println(myArray.length);
    System.out.println(found); 
}

1

Puede convertir su matriz int primitiva en una lista de matrices de enteros usando el siguiente código de Java 8,

List<Integer> arrayElementsList = Arrays.stream(yourArray).boxed().collect(Collectors.toList());

Y luego use el contains()método para verificar si la lista contiene un elemento en particular,

boolean containsElement = arrayElementsList.contains(key);

0

esto funcionó en java 8

public static boolean contains(final int[] array, final int key)
{
return Arrays.stream(array).anyMatch(n->n==key);
}

Debería regresar inmediatamente en la primera coincidencia, en su lugar, esto aún escaneará todos los elementos en la matriz, incluso si encontró la coincidencia. (Considere una variedad de trillones de artículos)
TriCore

Tiene razón, pruebe este booleano estático público contiene (matriz int final [], clave int final) {return Arrays.stream (matriz) .anyMatch (n-> n == clave); }
Farhad Baghirov

La secuencia anyMatch de Java 8 es una operación de cortocircuito y no escaneará todos los elementos de la matriz.
LordParsley

@LordParsley El objetivo del código anterior es verificar el elemento en la matriz, no escanear todos los elementos de la matriz.
Farhad Baghirov

Lo siento, veo que la respuesta fue editada. Solo estaba reiterando que era correcto, ya que no necesitará escanear todo si encuentra una parte.
LordParsley

0

Puede usar la java.util.Arraysclase para transformar la matriz T[?]en un List<T>objeto con métodos como contains:

Arrays.asList(int[] array).contains(int key);

-1

Dependiendo de qué tan grande sea su matriz de int, obtendrá un rendimiento mucho mejor si usa colecciones y en .containslugar de iterar sobre la matriz un elemento a la vez:

import static org.junit.Assert.assertTrue;
import java.util.HashSet;

import org.junit.Before;
import org.junit.Test;

public class IntLookupTest {

int numberOfInts = 500000;
int toFind = 200000;
int[] array;

HashSet<Integer> intSet;

@Before
public void initializeArrayAndSet() {
    array = new int[numberOfInts];
    intSet = new HashSet<Integer>();
    for(int i = 0; i < numberOfInts; i++) {
        array[i] = i;
        intSet.add(i);
    }
}

@Test
public void lookupUsingCollections() {
    assertTrue(intSet.contains(toFind));
}

@Test
public void iterateArray() {
    assertTrue(contains(array, toFind));

}

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}
}

-1

Solución # 1

Dado que la pregunta original solo quiere una solución simplificada (y no una más rápida), aquí hay una solución de una línea:

public boolean contains(int[] array, int key) {
    return Arrays.toString(array).matches(".*[\\[ ]" + key + "[\\],].*");
}

Explicación: Javadoc de Arrays.toString()estados que el resultado está entre corchetes y los elementos adyacentes están separados por los caracteres "," (una coma seguida de un espacio). Entonces podemos contar con esto. Primero convertimos arraya una cadena, y luego verificamos si keyestá contenida en esta cadena. Por supuesto, no podemos aceptar "subnúmeros" (por ejemplo, "1234" contiene "23"), así que tenemos que buscar patrones en los que keyesté precedido por un corchete de apertura o un espacio, y seguido por un corchete de cierre o una coma.

Nota: El patrón de expresiones regulares utilizado también maneja correctamente los números negativos (cuya representación de cadena comienza con un signo menos).

Solución # 2

Esta solución ya está publicada pero contiene errores, así que publico la solución correcta:

public boolean contains(int[] array, int key) {
    Arrays.sort(array);
    return Arrays.binarySearch(array, key) >= 0;
}

Además, esta solución tiene un efecto secundario: modifica el array(lo ordena).


String handlig es generalmente caro, ¿por qué alguien debería tratar ints como string?
Denys Vitali

@DenysVitali Porque op ya tiene una solución funcional y eficiente, y está buscando una solución más corta . Y estos son más cortos. Esta pregunta no se trata de rendimiento.
icza

Debería haber entendido mal la pregunta entonces, lo siento por preguntar
Denys Vitali

-5

Intenta Integer.parseInt()hacer esto .....

public boolean chkInt(final int[] array){
    int key = false;

    for (Integer i : array){


          try{

                   Integer.parseInt(i);
                   key = true;
                   return key;

             }catch(NumberFormatException ex){

                   key = false;

                   return key;

              }


     }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.