Jak mogę zająć się wykrywaniem (zwracaniem prawdy / fałszu), czy ArrayList zawiera więcej niż jeden taki sam element w Javie?
Wielkie dzięki, Terry
Edycja Zapomniałem wspomnieć, że nie chcę porównywać „bloków” ze sobą, ale ich wartości całkowite. Każdy „blok” ma int i to je wyróżnia. Znajduję int określonego bloku, wywołując metodę o nazwie „getNum” (np. Table1 [0] [2] .getNum ();
Odpowiedzi:
Najprostsze: zrzuć całą kolekcję do zestawu (za pomocą konstruktora Set (Collection) lub Set.addAll), a następnie sprawdź, czy zestaw ma taki sam rozmiar jak ArrayList.
Aktualizacja: Jeśli dobrze rozumiem twoje pytanie, masz 2d tablicę bloków, jak w
Tabela blokowa [] [];
i chcesz sprawdzić, czy któryś z nich ma duplikaty?
W takim przypadku mógłbym wykonać następujące czynności, zakładając, że Block poprawnie implementuje „equals” i „hashCode”:
Nie jestem tego w 100% pewien, jeśli chodzi o składnię, więc bezpieczniej byłoby napisać to jako
Set.add
zwraca wartość logiczną fałsz, jeśli dodawany element jest już w zestawie, więc możesz nawet zewrzeć i zbalansować każdy dodatek, który powróci,false
jeśli chcesz tylko wiedzieć, czy są jakieś duplikaty.źródło
Ulepszony kod, wykorzystujący zwracaną wartość
Set#add
zamiast porównywania rozmiaru listy i zestawu.źródło
Set<T> set = new HashSet<T>(list.size());
? Biorąc pod uwagę parametr listy, myślę, że jest bardziej wydajne, jeśli często lista nie zawiera duplikatów.HashSet
do rozmiaru listy spowoduje zmianę rozmiaru podczas przeglądania całej listy ze względu na podstawowy współczynnik ładowania struktury skrótu.Jeśli chcesz w ogóle uniknąć duplikatów, powinieneś po prostu odciąć środkowy proces wykrywania duplikatów i użyć zestawu .
źródło
Ulepszony kod zwracający zduplikowane elementy
źródło
Jeśli twoje elementy są w jakiś sposób porównywalne (fakt, że kolejność ma jakiekolwiek rzeczywiste znaczenie, jest obojętny - wystarczy, że jest zgodny z twoją definicją równości), najszybszym rozwiązaniem usuwania duplikatów będzie posortowanie listy (0 (n log ( n))), a następnie wykonać jedno przejście i poszukać powtórki elementów (czyli równych elementów, które następują po sobie) (to jest O (n)).
Ogólna złożoność wyniesie O (n log (n)), co jest mniej więcej tym samym, co uzyskasz za pomocą zbioru (n razy długi (n)), ale ze znacznie mniejszą stałą. Dzieje się tak, ponieważ stała sortowania / deduplikacji wynika z kosztu porównywania elementów, podczas gdy koszt z zestawu najprawdopodobniej będzie wynikał z obliczenia skrótu plus jedno (prawdopodobnie kilka) porównań hash. Jeśli używasz implementacji Set opartej na skrótach, to znaczy, ponieważ drzewo oparte na drzewie da ci O (n log² (n)), co jest jeszcze gorsze.
Jednak, jak rozumiem, nie musisz usuwać duplikatów, a jedynie testować ich istnienie. Więc powinieneś ręcznie zakodować algorytm scalania lub sortowania sterty w swojej tablicy, który po prostu kończy zwracając prawdę (tj. "Jest dup"), jeśli twój komparator zwraca 0, w przeciwnym razie kończy sortowanie i przeszukuje posortowaną tablicę testując powtórzenia . Rzeczywiście, w przypadku sortowania przez scalanie lub sortowanie po zakończeniu sortowania porównasz każdą zduplikowaną parę, chyba że oba elementy były już na swoich końcowych pozycjach (co jest mało prawdopodobne). Tak więc zmodyfikowany algorytm sortowania powinien przynieść ogromną poprawę wydajności (musiałbym to udowodnić, ale myślę, że zmodyfikowany algorytm powinien znajdować się w O (log (n)) na jednolicie losowych danych)
źródło
Musiałem wykonać podobną operację dla a
Stream
, ale nie mogłem znaleźć dobrego przykładu. Oto, co wymyśliłem.Ma to tę zaletę, że powoduje zwarcie, gdy duplikaty są wykrywane wcześnie, zamiast przetwarzania całego strumienia i nie jest dużo bardziej skomplikowane niż umieszczenie wszystkiego w a
Set
i sprawdzenie rozmiaru. Więc ten przypadek byłby mniej więcej taki:źródło
W Javie 8+ możesz używać Stream API:
źródło
Mówiąc najprościej: 1) upewnij się, że wszystkie elementy są porównywalne 2) posortuj tablicę 2) powtórz po tablicy i znajdź duplikaty
źródło
Aby poznać duplikaty na liście, użyj następującego kodu: Otrzymasz zestaw zawierający duplikaty.
źródło
najlepszym sposobem rozwiązania tego problemu jest użycie zestawu HashSet :
Po prostu wydrukuj arraylistę wyników i zobacz wynik bez duplikatów :)
źródło
Jeśli chcesz zestaw zduplikowanych wartości:
I prawdopodobnie pomyśl także o przycinaniu wartości lub używaniu małych liter ... w zależności od przypadku.
źródło
Uwaga: będzie to miało duży wpływ na wydajność, ponieważ elementy są usuwane z początku listy. Aby rozwiązać ten problem, mamy dwie możliwości. 1) wykonaj iterację w odwrotnej kolejności i usuń elementy. 2) Użyj LinkedList zamiast ArrayList. Ze względu na stronnicze pytania zadawane w wywiadach w celu usunięcia duplikatów z listy bez korzystania z innej kolekcji, powyższy przykład jest odpowiedzią. Jednak w prawdziwym świecie, jeśli będę musiał to osiągnąć, wstawię elementy z listy do zestawu, proste!
źródło
Przykład konkretnej klasy, która nadpisała
equals()
:źródło
źródło
Ta odpowiedź jest napisana w Kotlinie, ale można ją łatwo przetłumaczyć na Javę.
Jeśli rozmiar twojego arraylisty mieści się w stałym, małym zakresie, jest to świetne rozwiązanie.
źródło
źródło