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.
@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).
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.
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:
(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).
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.
@ 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:
publicstatic<T>boolean contains(final T[] array,final T v){for(final T e : array)if(e == v || v !=null&& v.equals(e))returntrue;returnfalse;}
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:
publicstatic<T>boolean contains2(final T[] array,final T v){if(v ==null){for(final T e : array)if(e ==null)returntrue;}else{for(final T e : array)if(e == v || v.equals(e))returntrue;}returnfalse;}
@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).
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.
publicstaticboolean binarySearch(String[] arr,String targetValue){int a =Arrays.binarySearch(arr, targetValue);return a >0;}
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.
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:
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 .:
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ą.
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.
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):
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:
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
Set<String> set =newHashSet<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:
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(...)
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ć:
TreeSet myElements =newTreeSet();// 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:
classMyComparatorimplementsComparator<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 comparatorTreeSet myElements =newTreeSet(newMyComparator());// 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);
Po co zawracać sobie głowę TreeSet? HashSetjest szybszy (O (1)) i nie wymaga zamawiania.
Sean Owen,
4
Spróbuj tego:
ArrayList<Integer> arrlist =newArrayList<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");}
Użyj następującego ( contains()metoda znajduje się ArrayUtils.in()w tym kodzie):
ObjectUtils.java
publicclassObjectUtils{/**
* 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.
*/publicstaticboolean equals(Object object1,Object object2){return object1==null? object2==null: object1.equals(object2);}}
ArrayUtils.java
publicclassArrayUtils{/**
* 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.
*/publicstatic<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)
*/publicstatic<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.
*/publicstatic<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.
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 =newString[]{"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}}
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 () .
publicboolean findString(String[] strings,String desired){for(String str : strings){if(desired.equals(str)){returntrue;}}returnfalse;//if we get here… there is no desired String, return false.}
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.
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
Odpowiedzi:
Ostrzeżenie: nie działa to dla tablic prymitywów (patrz komentarze).
Od java-8 możesz teraz używać strumieni.
Aby sprawdzić, czy tablica
int
,double
lublong
zawiera wartość użytkowąIntStream
,DoubleStream
lubLongStream
odpowiednio.Przykład
źródło
ArrayList
, ale niejava.util.ArrayList
jak można oczekiwać, prawdziwa klasa zwracany jest:java.util.Arrays.ArrayList<E>
zdefiniowana jako:public class java.util.Arrays {private static class ArrayList<E> ... {}}
.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
.„Biorąc pod uwagę ciąg znaków s, czy istnieje dobry sposób na sprawdzenie, czy WARTOŚCI zawierają 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):
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:
(Uwaga, możesz upuścić
new String[];
bit.)Tablice referencyjne są nadal złe i chcemy zestawu:
(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).
źródło
Arrays.asList
)?TreeSet
byłobyO(log n)
.HashSet
s 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.Możesz używać
ArrayUtils.contains
z Apache Commons Langpublic static boolean contains(Object[] array, Object objectToFind)
Zauważ, że ta metoda zwraca,
false
jeśli przekazana tablica tonull
.Dostępne są również metody prymitywnych tablic wszelkiego rodzaju.
Przykład:
źródło
Po prostu zaimplementuj go ręcznie:
Poprawa:
v != null
Warunkiem jest stała wewnątrz metody. Zawsze zwraca tę samą wartość logiczną podczas wywołania metody. Więc jeśli dane wejściowearray
są duże, bardziej efektywna jest ocena tego warunku tylko raz, a my możemy zastosować uproszczony / szybszy warunek wfor
pętli na podstawie wyniku. Ulepszonacontains()
metoda:źródło
Collection.contains(Object)
Arrays
iArrayList
okaże się, że niekoniecznie jest to szybsze niż wersjaArrays.asList(...).contains(...)
. Narzut związany z tworzeniem plikuArrayList
jest bardzo mały iArrayList.contains()
wykorzystuje bardziej inteligentną pętlę (w rzeczywistości wykorzystuje dwie różne pętle) niż ta pokazana powyżej (JDK 7).Cztery różne sposoby sprawdzania, czy tablica zawiera wartość
1) Korzystanie z listy:
2) Za pomocą zestawu:
3) Za pomocą prostej pętli:
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.
Szybki przykład:
źródło
(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”.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.
źródło
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:
W przypadku zastosowania tablicy 100 KB wyniki były następujące:
Więc jeśli tablica jest tworzona w posortowanej kolejności, wyszukiwanie binarne jest najszybsze, w przeciwnym razie
asList().contains
był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:
źródło
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 .:
Następnie możesz zrobić (jak wyżej):
źródło
W Javie 8 możesz utworzyć strumień i sprawdzić, czy wpisy w strumieniu są zgodne
"s"
:Lub jako metoda ogólna:
źródło
anyMatch
JavaDoc 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.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ą.
źródło
ObStupidAnswer (ale myślę, że gdzieś jest tu lekcja):
źródło
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:
W posortowanej tablicy:
Tak czy inaczej, HashSet dla wygranej.
źródło
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
źródło
Jedno możliwe rozwiązanie:
źródło
Programiści często:
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:
lub
Pierwszy jest bardziej czytelny niż drugi.
źródło
Użycie prostej pętli jest najbardziej wydajnym sposobem na zrobienie tego.
Dzięki uprzejmości Programcreek
źródło
W Javie 8 używaj strumieni.
źródło
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).
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
TreeSet
i dodaj do niego każdy element. Sortuje elementy i ma szybkąexist()
metodę (wyszukiwanie binarne).Jeśli elementy są zaimplementowane
Comparable
i chcesz odpowiednioTreeSet
posortować:ElementClass.compareTo()
metoda musi być kompatybilna zElementClass.equals()
: patrz Triady nie pojawiają się do walki? (Java Set brakuje elementu)W przeciwnym razie użyj własnego
Comparator
:Wypłata: sprawdź istnienie jakiegoś elementu:
źródło
TreeSet
?HashSet
jest szybszy (O (1)) i nie wymaga zamawiania.Spróbuj tego:
źródło
Użyj następującego (
contains()
metoda znajduje sięArrayUtils.in()
w tym kodzie):ObjectUtils.java
ArrayUtils.java
Jak widać w powyższym kodzie, że istnieją inne metody narzędziowe
ObjectUtils.equals()
iArrayUtils.indexOf()
, które były wykorzystywane w innych miejscach.źródło
Sprawdź to
źródło
else
dla 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 „).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 () .
źródło
Arrays.asList
nie jest O (n). To tylko lekkie opakowanie. Zobacz implementację.Jeśli nie chcesz, aby wielkość liter była uwzględniana
źródło
Służy
Array.BinarySearch(array,obj)
do znajdowania danego obiektu w tablicy lub nie.Przykład:
false - nie istnieje
źródło
Array.BinarySearch
iArray.FindIndex
są metodami .NET i nie istnieją w Javie.The array must be sorted prior to making this call. If it is not sorted, the results are undefined.
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.
źródło
Spróbuj użyć predykcyjnej metody testowej Java 8
Oto pełny tego przykład.
http://mytechnologythought.blogspot.com/2019/10/java-8-predicate-test-method-example.html
https://github.com/VipulGulhane1/java8/blob/master/Test.java
źródło
użycie a
Spliterator
zapobiega niepotrzebnemu wygenerowaniu aList
found == true
jeślisearch
jest zawarty w tablicyto czyni pracę dla tablic prymitywów
źródło
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
źródło
Możesz to sprawdzić na dwa sposoby
A) Konwertując tablicę na ciąg, a następnie sprawdź wymagany ciąg metodą .contains
B) jest to bardziej skuteczna metoda
źródło