Jak ustalić, czy tablica zawiera określoną wartość w Javie?

2275

Mam String[]z takimi wartościami:

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

Biorąc pod uwagę String s, czy istnieje dobry sposób na sprawdzenie, czy VALUESzawiera s?

Mike Sickler
źródło
5
Długa droga wokół niego, ale można użyć pętli for: "for (String s: Values) if (s.equals (" MYVALUE ")) return true;
Zack
70
@camickr. Na twoje pytanie głosowałem nad tym pytaniem i twoją odpowiedzią - teraz - ponieważ zaoszczędziło mi to 30 minut i 20 linii kodu paskudnego dla pętli, - teraz -. Nie przeczytałem tego trzy lata temu. (BTW, dzięki :))
Pościg
3
@ camickr - Mam prawie identyczną sytuację z tą: stackoverflow.com/a/223929/12943 Po prostu zdobywa głosy, ale to tylko kopia / wklej z dokumentacji firmy Sun. Myślę, że wynik zależy od tego, ile pomocy udzieliłeś, a nie od wysiłku włożonego w to - a przede wszystkim od tego, jak szybko go opublikujesz! Może natknęliśmy się na tajemnicę Johna Skeeta! Dobra odpowiedź, +1 dla ciebie.
Bill K
1
Jeśli używasz Apache Commons, org.apache.commons.lang.ArrayUtils.contains () zrobi to za Ciebie.
Mr. Boy,
34
@camickr, ponieważ ludzie, tacy jak ja, google pytanie, kliknij wynik SO, zobacz swoją odpowiedź, przetestuj ją, działa, głosuj odpowiedź, a następnie wyjdź.
Aequitas,

Odpowiedzi:

2920
Arrays.asList(yourArray).contains(yourValue)

Ostrzeżenie: nie działa to dla tablic prymitywów (patrz komentarze).


Od możesz teraz używać strumieni.

String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);

Aby sprawdzić, czy tablica int, doublelub longzawiera wartość użytkową IntStream, DoubleStreamlub LongStreamodpowiednio.

Przykład

int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
camickr
źródło
87
Jestem nieco ciekawy wydajności tego w porównaniu z funkcjami wyszukiwania w klasie Arrays w porównaniu do iteracji po tablicy i używania funkcji equals () lub == dla operacji pierwotnych.
Thomas Owens,
186
Nie tracisz dużo, ponieważ asList () zwraca ArrayList, która ma tablicę w sercu. Konstruktor po prostu zmieni odniesienie, więc nie ma tam wiele pracy do wykonania. I zawiera () / indexOf () będzie iterował i używał equals (). Jednak w przypadku prymitywów powinieneś lepiej kodować go samodzielnie. W przypadku łańcuchów lub innych klas różnica nie będzie zauważalna.
Joey,
18
Dziwne, NetBeans twierdzi, że „Arrays.asList (holidays)” dla „int [] holidays” zwraca „list <int []>”, a nie „list <int>”. Zawiera tylko jeden element. Oznacza, że ​​Contains nie działa, ponieważ ma tylko jeden element; tablica int.
Nyerguds,
62
Nyerguds: w rzeczywistości nie działa to w przypadku prymitywów. W języku Java pierwotne typy nie mogą być rodzajowe. asList jest zadeklarowany jako <T> Lista <T> asList (T ...). Po przekazaniu do niego int [] kompilator wyprowadza T = int [], ponieważ nie może wywnioskować T = int, ponieważ prymitywy nie mogą być ogólne.
CromTheDestroyer
28
@Joey tylko na marginesie, to jest ArrayList, ale nie java.util.ArrayListjak można oczekiwać, prawdziwa klasa zwracany jest: java.util.Arrays.ArrayList<E>zdefiniowana jako: public class java.util.Arrays {private static class ArrayList<E> ... {}}.
TWiStErRob 17.10.12
362

Zwięzła aktualizacja Java SE 9

Macierze referencyjne są złe. W tym przypadku jesteśmy po secie. Od wersji Java SE 9 mamy Set.of.

private static final Set<String> VALUES = Set.of(
    "AB","BC","CD","AE"
);

„Biorąc pod uwagę ciąg znaków s, czy istnieje dobry sposób na sprawdzenie, czy WARTOŚCI zawierają s?”

VALUES.contains(s)

O (1).

Odpowiedni rodzaj , niezmienny , O (1) i zwięzły . Piękny.*

Oryginalne szczegóły odpowiedzi

Po prostu wyczyść kod na początek. Mamy (poprawione):

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

Jest to zmienna statyczna, którą FindBugs powie ci, że jest bardzo niegrzeczna. Nie modyfikuj statyki i nie zezwalaj na to również innym kodom. Przy absolutnym minimum pole powinno być prywatne:

private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

(Uwaga, możesz upuścić new String[];bit.)

Tablice referencyjne są nadal złe i chcemy zestawu:

private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
     new String[] {"AB","BC","CD","AE"}
));

(Ludzie z paranoikami, tacy jak ja, mogą czuć się bardziej swobodnie, jeśli się w to zapakuje Collections.unmodifiableSet- może to nawet zostać upublicznione).

(* Mówiąc trochę więcej o marce, interfejs API kolekcji wciąż prawdopodobnie nie ma niezmiennych typów kolekcji, a składnia jest wciąż zbyt szczegółowa, jak na mój gust).

Tom Hawtin - tackline
źródło
184
Tylko że O (N) tworzy kolekcję w pierwszej kolejności :)
Drew Noakes,
60
Jeśli jest statyczny, prawdopodobnie będzie używany kilkakrotnie. Czas zainicjowania zestawu ma więc duże szanse na to, że będzie dość mały w porównaniu z kosztem wielu liniowych wyszukiwań.
Xr.
1
Utworzenie kolekcji będzie zdominowane przez czas ładowania kodu (który technicznie jest O (n), ale praktycznie stały).
Tom Hawtin - tackline
2
@ TomHawtin-tackline Dlaczego mówisz „w szczególności tutaj chcemy zestawu”? Jaka jest w tym przypadku zaleta zestawu (HashSet)? Dlaczego „tablica referencyjna” jest zła (przez „tablicę referencyjną”) rozumiesz przez to ArrayList wspierany przez tablicę wygenerowaną przez wywołanie do Arrays.asList)?
Basil Bourque,
6
@ nmr A TreeSetbyłoby O(log n). HashSets są skalowane w taki sposób, że średnia liczba elementów w wiadrze jest z grubsza stała. Przynajmniej dla tablic do 2 ^ 30. Mogą występować wpływy, powiedzmy, pamięci podręcznych sprzętu, które ignorowane są w analizie wielkiej litery. Zakłada również, że funkcja skrótu działa skutecznie.
Tom Hawtin - tackline
206

Możesz używać ArrayUtils.containsz Apache Commons Lang

public static boolean contains(Object[] array, Object objectToFind)

Zauważ, że ta metoda zwraca, falsejeśli przekazana tablica to null.

Dostępne są również metody prymitywnych tablic wszelkiego rodzaju.

Przykład:

String[] fieldsToInclude = { "id", "name", "location" };

if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
    // Do some stuff.
}
Intracer
źródło
4
@ max4ever Zgadzam się, ale wciąż jest to lepsze niż „kręcenie własnych” i łatwiejsze do odczytania niż surowa metoda Java.
Jason
38
@ max4ever Czasami masz już dołączoną tę bibliotekę (z innych powodów) i jest to całkowicie poprawna odpowiedź. Szukałem tego i już polegam na Apache Commons Lang. Dziękuję za tę odpowiedź.
GuiSim
1
Lub możesz po prostu skopiować metodę (i zależności, jeśli takie istnieją).
Buffalo,
10
@ max4ever Większość aplikacji na Androida jest minimalizowana przez Proguard, umieszczając w aplikacji tylko potrzebne klasy i funkcje. To sprawia, że ​​jest to równoznaczne z rzuceniem własnym lub skopiowaniem źródła rzeczy apache. A kto nie korzysta z tej minimalizacji, nie musi narzekać na 700kb lub 78kb :)
Kenyakorn Ketsombut
158

Po prostu zaimplementuj go ręcznie:

public static <T> boolean contains(final T[] array, final T v) {
    for (final T e : array)
        if (e == v || v != null && v.equals(e))
            return true;

    return false;
}

Poprawa:

v != nullWarunkiem jest stała wewnątrz metody. Zawsze zwraca tę samą wartość logiczną podczas wywołania metody. Więc jeśli dane wejściowe arraysą duże, bardziej efektywna jest ocena tego warunku tylko raz, a my możemy zastosować uproszczony / szybszy warunek w forpętli na podstawie wyniku. Ulepszona contains()metoda:

public static <T> boolean contains2(final T[] array, final T v) {
    if (v == null) {
        for (final T e : array)
            if (e == null)
                return true;
    } 
    else {
        for (final T e : array)
            if (e == v || v.equals(e))
                return true;
    }

    return false;
}
icza
źródło
9
@Phoexo To rozwiązanie jest oczywiście szybsze, ponieważ zaakceptowana odpowiedź zawija tablicę w listę i wywołuje metodę zawiera () na tej liście, podczas gdy moje rozwiązanie zasadniczo robi to, co zawiera tylko ().
icza 10.10.12
10
@AlastorMoody e == v wykonuje kontrolę równości odniesienia, która jest bardzo szybka. Jeśli ten sam obiekt (taki sam przez odniesienie) znajduje się w tablicy, zostanie odnaleziony szybciej. Jeśli nie jest to ta sama instancja, nadal może być taka sama jak deklarowana przez metodę equals (), to jest sprawdzane, jeśli odwołania nie są takie same.
icza
20
Dlaczego ta funkcja nie jest częścią Java? Nic dziwnego, że ludzie mówią, że Java jest rozdęta ... spójrz na wszystkie powyższe odpowiedzi, które używają wielu bibliotek, gdy wszystko, czego potrzebujesz, to pętla for. Dzieci w tych czasach!
phreakhead
4
@phreakhead Jest to część Java, patrzCollection.contains(Object)
Steve Kuo
11
@icza Jeśli spojrzysz na źródło Arraysi ArrayListokaże się, że niekoniecznie jest to szybsze niż wersja Arrays.asList(...).contains(...). Narzut związany z tworzeniem pliku ArrayListjest bardzo mały i ArrayList.contains()wykorzystuje bardziej inteligentną pętlę (w rzeczywistości wykorzystuje dwie różne pętle) niż ta pokazana powyżej (JDK 7).
Axel
72

Cztery różne sposoby sprawdzania, czy tablica zawiera wartość

1) Korzystanie z listy:

public static boolean useList(String[] arr, String targetValue) {
    return Arrays.asList(arr).contains(targetValue);
}

2) Za pomocą zestawu:

public static boolean useSet(String[] arr, String targetValue) {
    Set<String> set = new HashSet<String>(Arrays.asList(arr));
    return set.contains(targetValue);
}

3) Za pomocą prostej pętli:

public static boolean useLoop(String[] arr, String targetValue) {
    for (String s: arr) {
        if (s.equals(targetValue))
            return true;
    }
    return false;
}

4) Za pomocą Arrays.binarySearch ():

Poniższy kod jest niepoprawny, jest podany tutaj dla kompletności. Funkcja binarySearch () może być używana TYLKO na posortowanych tablicach. Przekonasz się, że wynik jest dziwny poniżej. Jest to najlepsza opcja podczas sortowania tablicy.

public static boolean binarySearch(String[] arr, String targetValue) {  
            int a = Arrays.binarySearch(arr, targetValue);
            return a > 0;
        }

Szybki przykład:

String testValue="test";
String newValueNotInList="newValue";
String[] valueArray = { "this", "is", "java" , "test" };
Arrays.asList(valueArray).contains(testValue); // returns true
Arrays.asList(valueArray).contains(newValueNotInList); // returns false
Sireesh Yarlagadda
źródło
5
twój przykład wyszukiwania binarnego powinien zwrócić> 0;
Will Sherwood,
6
Dlaczego? Myślę, że powinien zwrócić> 1, ponieważ 0 wskazuje, że jest on zawarty na początku tablicy.
poniedziałek
1
Pierwszy wariant z (a >= 0)był poprawny, po prostu sprawdź dokumenty , powiedzą: „Pamiętaj, że gwarantuje to, że zwracana wartość będzie wynosić> = 0, jeśli tylko klucz zostanie znaleziony”.
Yoory N.
Dlaczego działa na ciąg, a nie na int? static boolean istnieje (int [] ints, int k) {return Arrays.asList (ints) .contains (k); }
Willians Martins
71

Jeśli tablica nie zostanie posortowana, będziesz musiał iterować wszystko i wykonać wywołanie równości na każdym z nich.

Jeśli tablica jest posortowana, możesz przeprowadzić wyszukiwanie binarne, jest ona w klasie Arrays .

Ogólnie rzecz biorąc, jeśli zamierzasz przeprowadzić wiele kontroli członkostwa, możesz chcieć przechowywać wszystko w zestawie, a nie w tablicy.

Uri
źródło
1
Ponadto, jak powiedziałem w mojej odpowiedzi, jeśli użyjesz klasy Arrays, możesz posortować tablicę, a następnie przeprowadzić wyszukiwanie binarne na nowo posortowanej tablicy.
Thomas Owens,
1
@Thomas: Zgadzam się. Lub możesz po prostu dodać wszystko do TreeSet; ta sama złożoność. Użyłbym tablic, jeśli się nie zmieni (może zaoszczędzić trochę miejsca w pamięci, ponieważ odwołania są rozmieszczone w sposób ciągły, chociaż ciągi nie są). Użyłbym zestawu, gdyby to się zmieniło z czasem.
Uri
49

Za to, co warto, przeprowadziłem test porównujący 3 sugestie dotyczące prędkości. Wygenerowałem losowe liczby całkowite, przekonwertowałem je na String i dodałem do tablicy. Następnie szukałem najwyższej możliwej liczby / łańcucha, co byłoby najgorszym scenariuszem dla asList().contains().

W przypadku zastosowania tablicy o rozmiarze 10 KB wyniki były następujące:

Sortuj i szukaj: 15
Wyszukiwanie binarne: 0
asList.contains: 0

W przypadku zastosowania tablicy 100 KB wyniki były następujące:

Sortuj i szukaj: 156
Wyszukiwanie binarne: 0
asList.contains: 32

Więc jeśli tablica jest tworzona w posortowanej kolejności, wyszukiwanie binarne jest najszybsze, w przeciwnym razie asList().containsbyłoby to właściwe. Jeśli masz wiele wyszukiwań, warto posortować tablicę, aby móc korzystać z wyszukiwania binarnego. Wszystko zależy od twojej aplikacji.

Sądzę, że są to wyniki, których większość ludzi by się spodziewała. Oto kod testowy:

import java.util.*;

public class Test
{
    public static void main(String args[])
    {
        long start = 0;
        int size = 100000;
        String[] strings = new String[size];
        Random random = new Random();


        for (int i = 0; i < size; i++)
            strings[i] = "" + random.nextInt( size );

        start = System.currentTimeMillis();
        Arrays.sort(strings);
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Sort & Search : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Search        : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.asList(strings).contains( "" + (size - 1) ));
        System.out.println("Contains      : " + (System.currentTimeMillis() - start));
    }
}
camickr
źródło
6
Nie rozumiem tego kodu. Sortujesz „ciągi” tablicy i używasz tej samej (posortowanej) tablicy w obu wywołaniach binarySearch. Jak to może pokazywać cokolwiek oprócz optymalizacji środowiska wykonawczego HotSpot? To samo dotyczy połączenia asList.contains. Tworzysz listę z posortowanej tablicy, a następnie zawiera na niej najwyższą wartość. Oczywiście zajmie to trochę czasu. Jakie jest znaczenie tego testu? Nie wspominając o tym, że jest nieprawidłowo napisanym znakiem firmowym
Erik
Ponadto, ponieważ wyszukiwanie binarne można zastosować tylko do posortowanego zestawu, sortowanie i wyszukiwanie jest jedynym możliwym sposobem korzystania z wyszukiwania binarnego.
Erik
Sortowanie mogło być już wykonane z wielu innych powodów, np. Może być sortowane podczas inicjalizacji i nigdy nie zmieniane. Jest użyteczne w samodzielnym testowaniu czasu wyszukiwania. Tam, gdzie to spada, jest jednak mniej niż gwiezdny przykład znakowania mikrobenchowania. Znaki mikrodrobne są niezwykle trudne do uzyskania w Javie i powinny na przykład obejmować wykonanie kodu testowego wystarczającego do uzyskania optymalizacji punktu dostępowego przed uruchomieniem rzeczywistego testu, nie mówiąc już o uruchomieniu rzeczywistego kodu testowego więcej niż RAZ z zegarem. Przykładowe pułapki
Thor84no
7
Ten test jest wadliwy, ponieważ uruchamia wszystkie 3 testy w tej samej instancji JVM. Późniejsze testy mogłyby skorzystać z wcześniejszych testów podgrzewania pamięci podręcznej, JIT itp.
Steve Kuo
4
Ten test jest w rzeczywistości zupełnie niezwiązany. Sortowanie i wyszukiwanie ma złożoność liniową (n * log (n)), wyszukiwanie binarne jest logarytmiczne, a ArrayUtils.contains jest oczywiście liniowy. Nie ma sensu porównywać tych rozwiązań, ponieważ są one w zupełnie różnych klasach złożoności.
dragn
37

Zamiast używać również składni szybkiego inicjowania tablicy, możesz po prostu zainicjować ją jako Listę w podobny sposób, używając metody Arrays.asList, np .:

public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");

Następnie możesz zrobić (jak wyżej):

STRINGS.contains("the string you want to find");
Mark Rhodes
źródło
35

W Javie 8 możesz utworzyć strumień i sprawdzić, czy wpisy w strumieniu są zgodne "s":

String[] values = {"AB","BC","CD","AE"};
boolean sInArray = Arrays.stream(values).anyMatch("s"::equals);

Lub jako metoda ogólna:

public static <T> boolean arrayContains(T[] array, T value) {
    return Arrays.stream(array).anyMatch(value::equals);
}
assylias
źródło
3
Warto również zwrócić uwagę na prymitywne specjalizacje.
skiwi
Aby dodać, anyMatchJavaDoc stwierdza, że "...May not evaluate the predicate on all elements if not necessary for determining the result."tak, więc może nie być konieczne kontynuowanie przetwarzania po znalezieniu dopasowania.
mkobit,
28

Za pomocą klasy Arrays można wyszukiwać binarnie wartość. Jeśli twoja tablica nie jest posortowana, będziesz musiał użyć funkcji sortowania w tej samej klasie, aby posortować tablicę, a następnie przeszukaj ją.

Thomas Owens
źródło
Możesz użyć funkcji sortowania w tej samej klasie, aby to osiągnąć ... Powinienem dodać to do mojej odpowiedzi.
Thomas Owens,
1
Prawdopodobnie będzie to kosztować więcej niż podejście asList (). Zawiera (). Chyba że musisz to robić bardzo często (ale jeśli jest to tylko statyczna lista wartości, które można posortować na początek, żeby być uczciwym).
Joey,
Prawdziwe. Istnieje wiele zmiennych, które byłyby najbardziej skuteczne. Dobrze jest mieć opcje.
Thomas Owens,
Trochę kodu, który to robi tutaj: stackoverflow.com/a/48242328/9131078
OOBalance
Sortowanie całej tablicy na potrzeby wyszukiwania jest kosztowne. Możemy użyć tego samego czasu procesora dla samego wyszukiwania liniowej. Wolę wyszukiwanie binarne w kolekcji, która jest już wcześniej zbudowana w posortowanej kolejności.
arunwithasmile
17

ObStupidAnswer (ale myślę, że gdzieś jest tu lekcja):

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}
Tom Hawtin - tackline
źródło
1
Zgłaszanie wyjątków jest na pozór ciężkie, ale byłby to nowy sposób testowania wartości, jeśli zadziała. Minusem jest to, że wyliczenie należy wcześniej zdefiniować.
James P.
13

W rzeczywistości, jeśli użyjesz HashSet <String> zgodnie z sugestią Toma Hawtina, nie musisz się martwić sortowaniem, a Twoja prędkość jest taka sama jak w przypadku wyszukiwania binarnego na wstępnie ustawionej tablicy, prawdopodobnie nawet szybciej.

Wszystko zależy oczywiście od tego, jak skonfigurowany jest twój kod, ale z mojego punktu widzenia kolejność byłaby następująca:

W nieposortowanej tablicy:

  1. HashSet
  2. asList
  3. sortuj i binarnie

W posortowanej tablicy:

  1. HashSet
  2. Dwójkowy
  3. asList

Tak czy inaczej, HashSet dla wygranej.

nie
źródło
2
Członkostwo w HashSet powinno mieć wartość O (1), a wyszukiwanie binarne w posortowanej kolekcji to O (log n).
Skylar Saveland
11

Jeśli masz bibliotekę kolekcji Google, odpowiedź Toma można znacznie uprościć, używając ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html)

To naprawdę usuwa wiele bałaganu z proponowanej inicjalizacji

private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");
Jhodges
źródło
10

Jedno możliwe rozwiązanie:

import java.util.Arrays;
import java.util.List;

public class ArrayContainsElement {
  public static final List<String> VALUES = Arrays.asList("AB", "BC", "CD", "AE");

  public static void main(String args[]) {

      if (VALUES.contains("AB")) {
          System.out.println("Contains");
      } else {
          System.out.println("Not contains");
      }
  }
}
Christian Giménez
źródło
8

Programiści często:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

Powyższy kod działa, ale nie trzeba konwertować listy, aby ustawić ją jako pierwszą. Przekształcenie listy w zestaw wymaga dodatkowego czasu. Może to być tak proste jak:

Arrays.asList(arr).contains(targetValue);

lub

   for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }

return false;

Pierwszy jest bardziej czytelny niż drugi.

Jawad Zeb
źródło
7

Użycie prostej pętli jest najbardziej wydajnym sposobem na zrobienie tego.

boolean useLoop(String[] arr, String targetValue) {
    for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }
    return false;
}

Dzięki uprzejmości Programcreek

Ryan
źródło
Spowoduje to wygenerowanie wyjątku wskaźnika zerowego, jeśli tablica zawiera odwołanie zerowe przed wartością docelową.
Samuel Edwin Ward
1
instrukcja if powinna być: if (targetValue.equals (s)), ponieważ String equals ma funkcję sprawdzania instancji.
TheArchon
zamiast tego użyj Objects.equals (obj1, obj2), aby mieć wartość NULL.
trylogia
7

W Javie 8 używaj strumieni.

List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
Shineed Basheer
źródło
7
Czy takie podejście ma jakieś zalety?
Johannes Stadler,
1
To nie odpowiada na pytanie.
Florian F
5
  1. W przypadku tablic o ograniczonej długości użyj następujących (podanych przez camickr ). Jest to powolne w przypadku powtarzanych kontroli, szczególnie w przypadku dłuższych tablic (wyszukiwanie liniowe).

     Arrays.asList(...).contains(...)
  2. Dla szybkiej wydajności, jeśli wielokrotnie sprawdzasz w stosunku do większego zestawu elementów

    • Tablica ma niewłaściwą strukturę. Użyj a TreeSeti dodaj do niego każdy element. Sortuje elementy i ma szybką exist()metodę (wyszukiwanie binarne).

    • Jeśli elementy są zaimplementowane Comparablei chcesz odpowiednio TreeSetposortować:

      ElementClass.compareTo()metoda musi być kompatybilna z ElementClass.equals(): patrz Triady nie pojawiają się do walki? (Java Set brakuje elementu)

      TreeSet myElements = new TreeSet();
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
      // *Alternatively*, if an array is forceably provided from other code:
      myElements.addAll(Arrays.asList(myArray));
    • W przeciwnym razie użyj własnego Comparator:

      class MyComparator implements Comparator<ElementClass> {
           int compareTo(ElementClass element1; ElementClass element2) {
                // Your comparison of elements
                // Should be consistent with object equality
           }
      
           boolean equals(Object otherComparator) {
                // Your equality of comparators
           }
      }
      
      
      // construct TreeSet with the comparator
      TreeSet myElements = new TreeSet(new MyComparator());
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
    • Wypłata: sprawdź istnienie jakiegoś elementu:

      // Fast binary search through sorted elements (performance ~ log(size)):
      boolean containsElement = myElements.exists(someElement);
Glen Best
źródło
4
Po co zawracać sobie głowę TreeSet? HashSetjest szybszy (O (1)) i nie wymaga zamawiania.
Sean Owen,
4

Spróbuj tego:

ArrayList<Integer> arrlist = new ArrayList<Integer>(8);

// use add() method to add elements in the list
arrlist.add(20);
arrlist.add(25);
arrlist.add(10);
arrlist.add(15);

boolean retval = arrlist.contains(10);
if (retval == true) {
    System.out.println("10 is contained in the list");
}
else {
    System.out.println("10 is not contained in the list");
}
Mr.G
źródło
4

Użyj następującego ( contains()metoda znajduje się ArrayUtils.in()w tym kodzie):

ObjectUtils.java

public class ObjectUtils{

    /**
     * A null safe method to detect if two objects are equal.
     * @param object1
     * @param object2
     * @return true if either both objects are null, or equal, else returns false.
     */
    public static boolean equals(Object object1, Object object2){
        return object1==null ? object2==null : object1.equals(object2);
    }

}

ArrayUtils.java

public class ArrayUtils{

    /**
     * Find the index of of an object is in given array, starting from given inclusive index.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @param start  The index from where the search must start.
     * @return Index of the given object in the array if it is there, else -1.
     */
    public static <T> int indexOf(final T[] ts, final T t, int start){
        for(int i = start; i < ts.length; ++i)
            if(ObjectUtils.equals(ts[i], t))
                return i;
        return -1;
    }

    /**
     * Find the index of of an object is in given array, starting from 0;
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  indexOf(ts, t, 0)
     */
    public static <T> int indexOf(final T[] ts, final T t){
        return indexOf(ts, t, 0);
    }

    /**
     * Detect if the given object is in the given array.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  If indexOf(ts, t) is greater than -1.
     */
    public static <T> boolean in(final T[] ts, final T t){
        return indexOf(ts, t) > -1 ;
    }

}

Jak widać w powyższym kodzie, że istnieją inne metody narzędziowe ObjectUtils.equals()i ArrayUtils.indexOf(), które były wykorzystywane w innych miejscach.

Abhishek Oza
źródło
Jestem bardzo spóźniony, aby dołączyć do tej dyskusji, ale ponieważ moje podejście do rozwiązania tego problemu, kiedy zmierzyłem się z nim kilka lat temu, było nieco inne niż w innych odpowiedziach tutaj zamieszczonych, zamieszczam rozwiązanie, z którego wtedy korzystałem, tutaj, na wypadek gdyby ktoś uznał to za przydatne.
Abhishek Oza
3

Sprawdź to

String[] VALUES = new String[] {"AB","BC","CD","AE"};
String s;

for(int i=0; i< VALUES.length ; i++)
{
    if ( VALUES[i].equals(s) )
    { 
        // do your stuff
    } 
    else{    
        //do your stuff
    }
}
SubbaRao Boddu
źródło
1
To nie działa - będzie wprowadzić elsedla każdego elementu, który nie zgadza się (tak, jeśli szukasz dla „AB” w tej tablicy, to będzie tam 3 razy, ponieważ 3 wartości nie są „AB „).
Bernhard Barker
3

Arrays.asList () -> wtedy wywoływanie metody zawiera () zawsze będzie działać, ale algorytm wyszukiwania jest znacznie lepszy, ponieważ nie trzeba tworzyć lekkiego opakowania listy wokół tablicy, co robi Arrays.asList () .

public boolean findString(String[] strings, String desired){
   for (String str : strings){
       if (desired.equals(str)) {
           return true;
       }
   }
   return false; //if we get here… there is no desired String, return false.
}
TheArchon
źródło
Arrays.asListnie jest O (n). To tylko lekkie opakowanie. Zobacz implementację.
Patrick Parker,
3

Jeśli nie chcesz, aby wielkość liter była uwzględniana

Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
Akhil Babu K.
źródło
2

Służy Array.BinarySearch(array,obj)do znajdowania danego obiektu w tablicy lub nie.

Przykład:

if (Array.BinarySearch(str, i) > -1)`  true --exists

false - nie istnieje

Mściciel
źródło
4
Array.BinarySearchi Array.FindIndexsą metodami .NET i nie istnieją w Javie.
ataylor
@ataylor jest Arrays.binarySearch w java. Ale masz rację, nie Arrays.findIndex
mente
Należy zauważyć:The array must be sorted prior to making this call. If it is not sorted, the results are undefined.
Dorian Gray
1

Utwórz wartość logiczną początkowo ustawioną na false. Uruchom pętlę, aby sprawdzić każdą wartość w tablicy i porównać z wartością, którą sprawdzasz. Jeśli kiedykolwiek otrzymasz dopasowanie, ustaw wartość logiczną na true i zatrzymaj zapętlenie. Następnie zapewnij, że wartość logiczna jest prawdziwa.

mandy1339
źródło
1

Spróbuj użyć predykcyjnej metody testowej Java 8

Oto pełny tego przykład.

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Test {
 public static final List<String> VALUES = Arrays.asList("AA", "AB", "BC", "CD", "AE");

 public static void main(String args[]) {
  Predicate<String> containsLetterA = VALUES -> VALUES.contains("AB");
  for (String i : VALUES) {

   System.out.println(containsLetterA.test(i));
  } 
 }
}

http://mytechnologythought.blogspot.com/2019/10/java-8-predicate-test-method-example.html

https://github.com/VipulGulhane1/java8/blob/master/Test.java

Vipul Gulhane
źródło
0

użycie a Spliterator zapobiega niepotrzebnemu wygenerowaniu a List

boolean found = false;  // class variable

String search = "AB";
Spliterator<String> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
while( (! found) && spl.tryAdvance(o -> found = o.equals( search )) );

found == truejeśli searchjest zawarty w tablicy


to czyni pracę dla tablic prymitywów

public static final int[] VALUES = new int[] {1, 2, 3, 4};
boolean found = false;  // class variable

int search = 2;
Spliterator<Integer> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
Kaplan
źródło
0

Ponieważ mam do czynienia z językiem Java niskiego poziomu przy użyciu pierwotnych typów bajtów i bajtów [], najlepsze, jakie dotychczas uzyskałem, to bajty-java https://github.com/patrickfav/bytes-java wydaje się być świetnym kawałkiem pracy

typelogiczny
źródło
-2

Możesz to sprawdzić na dwa sposoby

A) Konwertując tablicę na ciąg, a następnie sprawdź wymagany ciąg metodą .contains

 String a=Arrays.toString(VALUES);
    System.out.println(a.contains("AB"));
    System.out.println(a.contains("BC"));
    System.out.println(a.contains("CD"));
    System.out.println(a.contains("AE"));

B) jest to bardziej skuteczna metoda

 Scanner s=new Scanner(System.in);


   String u=s.next();
   boolean d=true;
    for(int i=0;i<VAL.length;i++)
    {
        if(VAL[i].equals(u)==d)
            System.out.println(VAL[i] +" "+u+VAL[i].equals(u));  

    }
Syed Salman Hassan
źródło
1
Konwersja łańcucha jest absurdalnie nieefektywna, a rozwiązanie jest niepoprawne, np. Zawiera („,”) zwróci true.
Atuos