Java, vérification simplifiée si le tableau int contient int


94

Fondamentalement, mon compagnon a dit que je pourrais raccourcir mon code en utilisant une manière différente de vérifier si un tableau int contient un int, bien qu'il ne me dise pas ce que c'est: P.

Actuel:

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

J'ai également essayé cela, bien que cela renvoie toujours faux pour une raison quelconque.

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

Quelqu'un pourrait m'aider?

Je vous remercie.


8
Votre appel Arrays.asList (...) prend un vararg, c'est-à-dire qu'il encapsulera le nombre arbitraire d'arguments que vous pourriez y passer dans une liste. Dans votre cas, vous obtenez une liste de tableaux avec un seul élément, et cette liste ne contient évidemment pas l'int.
sarcan

Votre commentaire veut dire quoi maintenant?
sarcan

vérification de la Hashsetréponse du mécanisme de réexamen. C'est le moyen le plus rapide.
Amit Deshpande

Je ne vois aucun intérêt à raccourcir votre code d'origine car votre argument est un tableau primitif et votre code est très clair et direct. ArrayListla mise en œuvre fait de même.
Genzer

Je ne réduirais pas votre code. (1) arraylist fait la même chose que vous. (2) - le plus important est que le code raccourci utilisant Arrays.asList crée un nouvel objet, ce qui pourrait poser problème dans certains codes critiques pour les performances. Le premier extrait de code est la meilleure chose que vous puissiez faire.
Martin Podval

Réponses:


38

Voici la solution Java 8

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

63

Vous pouvez simplement utiliser ArrayUtils.containsde Apache Commons Lang library.

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

1
Tant que vous utilisez ArrayUtils, y a-t-il une raison de ne pas utiliser ArrayUtils.contains
mjohnsonengr

2
Aucune raison du tout :)
Reimeus

20
Il est à noter que cela ArrayUtils.contains()fait partie de la Apache Commons Langbibliothèque. Même si c'est une excellente bibliothèque, ce n'est probablement pas une bonne idée d'ajouter une dépendance externe juste pour vérifier si le tableau contient un élément: D
Krzysiek

2
ArrayUtils appartient au passé. Java 8+ et Guava ont des goodies assez incroyables !!
TriCore

34

C'est parce que Arrays.asList(array)revenir List<int[]>. arrayL'argument est traité comme une valeur que vous souhaitez encapsuler (vous obtenez une liste de tableaux d'entiers), et non comme vararg.

Notez qu'il ne travail avec les types d'objet (pas primitives):

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

ou même:

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

Mais vous ne pouvez pas l'avoir List<int>et la boxe automatique ne fonctionne pas ici.


1
Pourquoi l'autoboxing ne fonctionne pas, est-ce parce qu'elle est déclarée définitive?
subhashis

19

Guava propose des méthodes supplémentaires pour les types primitifs. Parmi eux, une méthode contient qui prend les mêmes arguments que le vôtre.

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

Vous pouvez également importer statiquement la version goyave.

Voir les primitives de goyave expliquées


18

Une manière différente:

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

Cela modifie le tableau transmis. Vous auriez la possibilité de copier le tableau et de travailler sur le tableau d'origine, c'est-à-dire int[] sorted = array.clone();
mais ce n'est qu'un exemple de code court. Le runtime est O(NlogN)pendant que votre chemin estO(N)


30
Je pense que je serais surpris si une containsméthode modifiait mon tableau.
Zong

@ZongLi: Ceci est juste un exemple pour l'OP Mise à jour de l'OP si nous sommes pinaillés
Cratylus

5
De javadoc de binarySearch (): "la valeur de retour sera> = 0 si et seulement si la clé est trouvée." donc Arrays.binarySearch (array, key)> = 0 doit être renvoyé!
icza

Supplément: La valeur de retour de binarySearch () est (- (point d'insertion) - 1) si la clé n'est pas contenue, ce qui peut probablement être une valeur différente de -1.
icza

Cela ne peut pas être -1si cela a l'intention d'être vrai. "Le point d'insertion est défini comme le point auquel la clé serait insérée dans la liste: l'index du premier élément supérieur à la clé, ou list.size () si tous les éléments de la liste sont inférieurs à la clé spécifiée. ". Besoin de dire >= 0.
Brian

17

Je sais qu'il est super tard, mais essayez à la Integer[]place int[].


Telle est la solution.
atheesh27

Upvote pour la réponse de travail, merci Willy
ucMedia

1

1. utilisations ponctuelles

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

2. utilisez HashSet pour des considérations de performances si vous en utilisez plusieurs fois.

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

1

Essaye ça:

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

Vous pouvez convertir votre tableau int primitif en un tableau d'entiers en utilisant le code Java 8 ci-dessous,

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

Et puis utilisez la contains()méthode pour vérifier si la liste contient un élément particulier,

boolean containsElement = arrayElementsList.contains(key);

0

cela a fonctionné en java 8

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

Il devrait immédiatement revenir sur la première correspondance, à la place, cela analysera toujours tous les éléments du tableau, même s'il a trouvé la correspondance. (Considérez un tableau d'articles trilion)
TriCore

Vous avez raison d'essayer ce booléen statique public contient (tableau int final [], clé int finale) {return Arrays.stream (tableau) .anyMatch (n-> n == clé); }
Farhad Baghirov

Java 8 stream anyMatch est une opération de court-circuit et n'analysera pas tous les éléments du tableau.
LordParsley

@LordParsley Le but du code ci-dessus est de vérifier l'élément dans le tableau, pas de balayer tous les éléments du tableau.
Farhad Baghirov

Désolé, je vois que la réponse a été modifiée. Je répétais juste que c'était correct car il n'aura pas besoin de tout scanner s'il en trouve un à mi-chemin.
LordParsley

0

Vous pouvez utiliser la java.util.Arraysclasse pour transformer le tableau T[?]en un List<T>objet avec des méthodes telles que contains:

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

-1

Selon la taille de votre tableau d'entiers, vous obtiendrez de bien meilleures performances si vous utilisez des collections et .containsplutôt que d'itérer sur le tableau un élément à la fois:

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

Solution n ° 1

Étant donné que la question d'origine ne veut qu'une solution simplifiée (et non plus rapide), voici une solution en une ligne:

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

Explication: Javadoc d' Arrays.toString()états, le résultat est placé entre crochets et les éléments adjacents sont séparés par les caractères "," (une virgule suivie d'un espace). Nous pouvons donc compter sur cela. Nous convertissons arrayd'abord en une chaîne, puis nous vérifions si elle keyest contenue dans cette chaîne. Bien sûr, nous ne pouvons pas accepter les "sous-nombres" (par exemple "1234" contient "23"), nous devons donc rechercher des modèles où le keyest précédé d'un crochet ouvrant ou d'un espace, et suivi d'un crochet fermant ou d'une virgule.

Remarque: Le modèle d'expression régulière utilisé gère également correctement les nombres négatifs (dont la représentation sous forme de chaîne commence par un signe moins).

Solution n ° 2

Cette solution est déjà publiée mais elle contient des erreurs, je poste donc la bonne solution:

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

Cette solution a également un effet secondaire: elle modifie le array(le trie).


Le handlig de chaîne est généralement cher, pourquoi quelqu'un devrait-il traiter les entiers comme une chaîne?
Denys Vitali

@DenysVitali Parce qu'op a déjà une solution efficace et fonctionnelle, et qu'il recherche une solution plus courte . Et ceux-ci sont plus courts. Cette question ne concerne pas les performances.
icza

J'aurais dû mal comprendre la question alors, désolé de l'avoir posée
Denys Vitali

-5

Essayez Integer.parseInt()de faire ceci .....

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;

              }


     }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.