Java, Uproszczone sprawdzenie, czy tablica int zawiera int

96

Zasadniczo mój kolega powiedział, że mogę skrócić kod, używając innego sposobu sprawdzania, czy tablica int zawiera int, chociaż nie powie mi, co to jest: P.

Obecny:

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

Próbowałem również tego, chociaż z jakiegoś powodu zawsze zwraca to fałsz.

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

Czy ktoś mógłby mi pomóc?

Dziękuję Ci.

Caleb
źródło
8
Twoje wywołanie Arrays.asList (...) przyjmuje wartość vararg, co oznacza, że ​​zawinie dowolną liczbę argumentów, które możesz przekazać w liście. W twoim przypadku otrzymujesz listę tablic z jednym elementem, a ta lista oczywiście nie zawiera int.
sarcan
Twój komentarz oznacza co teraz?
sarcan
sprawdź Hashsetodpowiedź mechanizmu ponownej próby. To najszybszy sposób.
Amit Deshpande
Nie widzę sensu w skracaniu oryginalnego kodu, ponieważ argument jest prostą tablicą, a kod jest bardzo jasny i bezpośredni. ArrayListrealizacja robi to samo.
Genzer
Nie skróciłbym twojego kodu. (1) arraylist robi to samo co ty. (2) - ważniejsze jest to, że skracanie kodu za pomocą Arrays.asList tworzy nowy obiekt, który może być problemem w przypadku kodu krytycznego dla wydajności. Pierwszy fragment kodu to najlepsza rzecz, jaką możesz zrobić.
Martin Podval,

Odpowiedzi:

41

Oto rozwiązanie Java 8

public static boolean contains(final int[] arr, final int key) {
    return Arrays.stream(arr).anyMatch(i -> i == key);
}
TriCore
źródło
64

Możesz po prostu użyć ArrayUtils.containsfrom Apache Commons Lang library.

public boolean contains(final int[] array, final int key) {     
    return ArrayUtils.contains(array, key);
}
Reimeus
źródło
1
Tak długo jak używasz ArrayUtils, czy istnieje jakikolwiek powód, aby nie używać ArrayUtils.contains
mjohnsonengr
2
Bez powodu :)
Reimeus,
20
Warto zauważyć, że ArrayUtils.contains()jest to część Apache Commons Langbiblioteki. Mimo że to świetna biblioteka, prawdopodobnie nadal nie jest dobrym pomysłem dodawanie zewnętrznej zależności tylko po to, aby sprawdzić, czy tablica zawiera element: D
Krzysiek
2
ArrayUtils to już przeszłość. Java 8+ i Guava mają niesamowite gadżety !!
TriCore
34

To dlatego, że Arrays.asList(array)wrócę List<int[]>. arrayargument jest traktowany jako jedna wartość, którą chcesz opakować (dostajesz listę tablic int), a nie jako vararg.

Zauważ, że to czyni pracę z typów obiektów (nie prymitywów):

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

lub nawet:

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

Ale nie możesz, List<int>a autoboxing tu nie działa.

Tomasz Nurkiewicz
źródło
1
Dlaczego autoboxing nie działa, czy to dlatego, że został uznany za ostateczny?
subhashis
19

Guawa oferuje dodatkowe metody dla typów pierwotnych. Wśród nich jest metoda zawierająca te same argumenty, co Twoja.

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

Równie dobrze możesz zaimportować statycznie wersję guawy.

Zobacz wyjaśnienie prymitywów guawy

Wynicować
źródło
18

Inny sposób:

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

To modyfikuje przekazaną tablicę. Mógłbyś skopiować tablicę i pracować na oryginalnej tablicy, tj. int[] sorted = array.clone();
Ale to jest tylko przykład krótkiego kodu. Środowisko wykonawcze jest O(NlogN)zgodne z oczekiwaniamiO(N)

Cratylus
źródło
30
Myślę, że byłbym zaskoczony, gdyby containsmetoda zmodyfikowała moją tablicę.
Zong
@ZongLi: To tylko przykład dla OP.Uaktualniony OP, jeśli szukamy dziury w
dziobie
5
Z javadoc funkcji binarySearch (): "wartość zwracana będzie> = 0 wtedy i tylko wtedy, gdy klucz zostanie znaleziony." więc powinno zostać zwrócone Arrays.binarySearch (tablica, klucz)> = 0!
icza
Suplement: Wartość zwracana przez binarySearch () to (- (punkt wstawienia) - 1), jeśli klucz nie jest zawarty, co może być wartością inną niż -1.
icza
Nie może tak być, -1jeśli ma to być prawda. „Punkt wstawienia jest zdefiniowany jako punkt, w którym klucz zostałby wstawiony do listy: indeks pierwszego elementu większy niż klucz lub lista.size (), jeśli wszystkie elementy na liście są mniejsze niż określony klucz. ”. Muszę powiedzieć >= 0.
Brian
17

Wiem, że jest bardzo późno, ale spróbuj Integer[]zamiast tego int[].

Willy Wonka
źródło
To jest rozwiązanie.
atheesh 27
1

1. jednorazowe zastosowania

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

2. użyj HashSet do rozważenia wydajności, jeśli używasz więcej niż raz.

Set <T>set =new HashSet<T>(Arrays.asList(...));
set.contains(...)
Jaskey
źródło
1

Spróbuj tego:

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); 
}
Elavarasan S
źródło
1

Możesz przekonwertować swoją prymitywną tablicę int na tablicę liczb całkowitych, używając poniższego kodu Java 8,

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

Następnie użyj contains()metody, aby sprawdzić, czy lista zawiera konkretny element,

boolean containsElement = arrayElementsList.contains(key);
Hetal Rachh
źródło
0

to działało w java 8

public static boolean contains(final int[] array, final int key)
{
return Arrays.stream(array).anyMatch(n->n==key);
}
Farhad Baghirov
źródło
Powinien natychmiast powrócić przy pierwszym dopasowaniu, zamiast tego nadal skanuje wszystkie elementy w tablicy, nawet jeśli znalazł dopasowanie. (Rozważ tablicę trylionów pozycji)
TriCore
Masz rację, spróbuj tego publicznego statycznego boolowskiego zawiera (ostatnia tablica int [], końcowy klucz int) {return Arrays.stream (tablica) .anyMatch (n-> n == klucz); }
Farhad Baghirov
Java 8 stream anyMatch to operacja zwarcia i nie skanuje wszystkich elementów w tablicy.
LordParsley
@LordParsley Celem powyższego kodu jest sprawdzenie elementu w tablicy, a nie skanowanie całego elementu tablicy.
Farhad Baghirov
Przepraszam, widzę, że odpowiedź została zmieniona. Powtarzałem tylko, że było to poprawne, ponieważ nie będzie musiał skanować wszystkiego, jeśli znajdzie jedną część drogi.
LordParsley
0

Możesz użyć java.util.Arraysclass do transformacji tablicy T[?]w List<T>obiekcie metodami takimi jak contains:

Arrays.asList(int[] array).contains(int key);
Mourad El Aomari
źródło
-1

W zależności od tego, jak duża będzie twoja tablica int, uzyskasz znacznie lepszą wydajność, jeśli użyjesz kolekcji i .containszamiast iterować po tablicy po jednym elemencie naraz:

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;
}
}
Kaveh Ghahremani
źródło
-1

Rozwiązanie nr 1

Ponieważ pierwotne pytanie dotyczy tylko uproszczonego rozwiązania (a nie szybszego), oto rozwiązanie jednowierszowe:

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

Objaśnienie: Javadoc Arrays.toString()stanów wynik jest ujęty w nawiasy kwadratowe, a sąsiednie elementy są oddzielone znakami „,” (przecinek, po którym następuje spacja). Więc możemy na to liczyć. Najpierw konwertujemy arrayna ciąg, a następnie sprawdzamy, czy keyjest w nim zawarty. Oczywiście nie możemy zaakceptować „numerów podrzędnych” (np. „1234” zawiera „23”), więc musimy szukać wzorców, w których keypoprzedzony jest nawiasem otwierającym lub spacją, po którym następuje nawias zamykający lub przecinek.

Uwaga: użyty wzorzec wyrażenia regularnego również poprawnie obsługuje liczby ujemne (których reprezentacja w postaci łańcucha zaczyna się od znaku minus).

Rozwiązanie nr 2

To rozwiązanie jest już opublikowane, ale zawiera błędy, więc zamieszczam poprawne rozwiązanie:

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

Również to rozwiązanie ma efekt uboczny: modyfikuje array(sortuje).

icza
źródło
Obsługa ciągów jest ogólnie kosztowna, dlaczego ktoś miałby traktować int jako ciąg?
Denys Vitali
@DenysVitali Ponieważ op ma już działające, wydajne rozwiązanie i szuka krótszego rozwiązania. A te są krótsze. To pytanie nie dotyczy wydajności.
icza
Powinienem był wtedy źle zrozumieć pytanie, przepraszam, że pytam
Denys Vitali
-5

Spróbuj Integer.parseInt()to zrobić .....

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;

              }


     }
}
Kumar Vivek Mitra
źródło