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.


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);
}

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);
}

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.


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


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)


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


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(...)

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); 
}

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);

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);
}

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);

-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;
}
}

-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).


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;

              }


     }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.