Java, verificação simplificada se o array int contém int


94

Basicamente, meu amigo tem dito que eu poderia tornar meu código mais curto usando uma maneira diferente de verificar se um array int contém um int, embora ele não me diga o que é: P.

Atual:

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

Também tentei fazer isso, embora sempre retorne falso por algum motivo.

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

Alguém poderia me ajudar?

Obrigado.


8
Sua chamada a Arrays.asList (...) leva um vararg, ou seja, envolverá o número arbitrário de argumentos que você pode passar para isso em uma Lista. No seu caso, você está obtendo uma lista de arrays com um único elemento, e essa lista obviamente não contém o int.
sarcan

Seu comentário significa e agora?
sarcan

verificar a Hashsetresposta do mecanismo de nova tentativa com base. É o caminho mais rápido.
Amit Deshpande de

Não vejo nenhum ponto em tornar seu código original mais curto, já que seu argumento é uma matriz primitiva e seu código é muito claro e direto. ArrayListimplementação está fazendo o mesmo.
Genzer

Eu não tornaria seu código mais curto. (1) arraylist faz a mesma coisa que você. (2) - o mais importante é que o código reduzido usando Arrays.asList cria um novo objeto, o que pode ser um problema em algum código de desempenho crítico. O primeiro trecho de código é a melhor coisa que você pode fazer.
Martin Podval

Respostas:


38

Aqui está a solução Java 8

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

63

Você pode simplesmente usar ArrayUtils.containsde Apache Commons Lang library.

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

1
Contanto que você esteja usando ArrayUtils, há alguma razão para não usar ArrayUtils.contains
mjohnsonengr

2
Nenhum motivo :)
Reimeus

20
Vale ressaltar que ArrayUtils.contains()faz parte da Apache Commons Langbiblioteca. Mesmo que seja uma ótima lib, provavelmente ainda não é uma boa ideia adicionar dependência externa apenas para verificar se o array contém um elemento: D
Krzysiek

2
ArrayUtils é coisa do passado. Java 8+ e Guava têm guloseimas incríveis !!
TriCore

34

É porque Arrays.asList(array)volte List<int[]>. arrayargumento é tratado como um valor que você deseja agrupar (você obtém uma lista de arrays de ints), não como vararg.

Note-se que ele faz o trabalho com tipos de objeto (não primitivos):

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

ou mesmo:

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

Mas você não pode ter List<int>e autoboxing não está funcionando aqui.


1
Por que o autoboxing não funciona, é porque foi declarado como final?
subhashis em

19

O Guava oferece métodos adicionais para tipos primitivos. Entre eles, um método contém que leva os mesmos argumentos que o seu.

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

Você também pode importar estaticamente a versão goiaba.

Veja os primitivos de goiaba explicados


18

Uma maneira diferente:

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

Isso modifica a matriz passada. Você teria a opção de copiar o array e trabalhar no array original, ou seja, int[] sorted = array.clone();
mas este é apenas um exemplo de código curto. O tempo de execução é O(NlogN)enquanto o seu caminho éO(N)


30
Acho que ficaria surpreso se um containsmétodo modificasse meu array.
Zong

@ZongLi: Este é apenas um exemplo para o OP. OP atualizado se formos picantes
Cratylus

5
De javadoc de binarySearch (): "o valor de retorno será> = 0 se e somente se a chave for encontrada." então Arrays.binarySearch (array, key)> = 0 deve ser retornado!
icza

Suplemento: O valor de retorno de binarySearch () é (- (ponto de inserção) - 1) se a chave não estiver contida, o que provavelmente pode ser um valor diferente de -1.
icza

Isso não pode ser -1se for a intenção de ser verdade. "O ponto de inserção é definido como o ponto em que a chave seria inserida na lista: o índice do primeiro elemento maior do que a chave ou list.size () se todos os elementos da lista forem menores do que a chave especificada. " Precisa dizer >= 0.
Brian,


1

1. usos únicos

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

2. use HashSet para consideração de desempenho se você usar mais de uma vez.

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

1

Experimente isto:

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

Você pode converter sua matriz primitiva int em uma lista de números inteiros usando o código Java 8 abaixo,

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

E então use o contains()método para verificar se a lista contém um elemento específico,

boolean containsElement = arrayElementsList.contains(key);

0

isso funcionou em java 8

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

Ele deve retornar imediatamente na primeira correspondência, em vez disso, ainda fará a varredura de todos os itens na matriz, mesmo que tenha encontrado a correspondência. (Considere uma série de itens trilionários)
TriCore

Você está certo, tente este booleano estático público contém (array final int [], chave int final) {return Arrays.stream (array) .anyMatch (n-> n == chave); }
Farhad Baghirov

Java 8 stream anyMatch é uma operação de curto-circuito e não fará a varredura de todos os itens no array.
LordParsley,

@LordParsley O objetivo do código acima é verificar o elemento do array, não varrer todos os elementos do array.
Farhad Baghirov

Desculpe, vejo que a resposta foi editada. Eu estava apenas reiterando que estava correto, pois não será necessário verificar tudo se encontrar uma parte do caminho.
LordParsley

0

Você pode usar a java.util.Arraysclasse para transformar a matriz T[?]em um List<T>objeto com métodos como contains:

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

-1

Dependendo de quão grande será a sua matriz de int, você obterá um desempenho muito melhor se usar coleções e em .containsvez de iterar na matriz um elemento por 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

Solução # 1

Uma vez que a pergunta original deseja apenas uma solução simplificada (e não mais rápida), aqui está uma solução de uma linha:

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

Explicação: Javadoc de Arrays.toString()estados, o resultado é colocado entre colchetes e os elementos adjacentes são separados pelos caracteres "," (uma vírgula seguida por um espaço). Portanto, podemos contar com isso. Primeiro, convertemos arraypara uma string e, em seguida, verificamos se keyessa string está contida. Claro que não podemos aceitar "subnúmeros" (por exemplo, "1234" contém "23"), então temos que procurar padrões onde o keyseja precedido por um colchete de abertura ou um espaço e seguido por um colchete de fechamento ou vírgula.

Nota: O padrão regexp usado também lida corretamente com números negativos (cuja representação de string começa com um sinal de menos).

Solução # 2

Esta solução já foi postada mas contém erros, então posto a solução correta:

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

Além disso, esta solução tem um efeito colateral: ela modifica o array(ordena).


Handlig de corda é geralmente caro, por que alguém deveria tratar ints como corda?
Denys Vitali

@DenysVitali Porque op já tem uma solução eficiente e funcional e está procurando uma solução mais curta . E estes são mais curtos. Esta questão não é sobre desempenho.
icza

Eu deveria ter entendido mal a pergunta então, desculpe por perguntar
Denys Vitali

-5

Tente Integer.parseInt()fazer isso ...

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;

              }


     }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.