Mam listę typu Integer np:
[1, 1, 2, 3, 3, 3]
Chciałbym, aby metoda zwracała wszystkie duplikaty np:
[1, 3]
Jaki jest najlepszy sposób, aby to zrobić?
java
collections
najświeższe
źródło
źródło
Odpowiedzi:
Metoda
add
zSet
Zwraca wartość logiczną, czy wartość już istnieje (true, jeśli nie istnieje, fałsz, jeśli już istnieje, patrz zestaw dokumentacji ).Po prostu powtórz wszystkie wartości:
źródło
for (Integer yourInt
, aby uniknąć niepotrzebnego pakowania i rozpakowywania, zwłaszcza, że twoje wejście zawiera jużInteger
s.HashSet
ciebie również musisz wziąć pod uwagę współczynnik obciążenia, np. Kiedy określasz pojemność początkową wynoszącą100
, ponieważ chcesz dodać tę liczbę elementów, zostanie ona zaokrąglona do następnej potęgi 2 (128
), co oznacza, że z domyślnym współczynnikiem obciążenia0.75f
równym próg zmiany rozmiaru będzie96
, więc zmiana rozmiaru nastąpi przed dodaniem100
elementów. Na szczęście zmiana rozmiaru nie jest już taka droga. W aktualnych środowiskach JRE zmiana rozmiaru nie jest już ponownie mieszana, elementy są po prostu rozdzielane między dwie możliwe lokalizacje wyników na podstawie odpowiedniego bitu.Potrzebowałem również rozwiązania tego problemu. Użyłem rozwiązania Leifga i uczyniłem go ogólnym.
źródło
Wziąłem rozwiązanie Johna Stricklera i przerobiłem je, aby korzystało z interfejsu API strumieni wprowadzonego w JDK8:
źródło
distinct()
metoda jest również stanowa. Nie mogę wymyślić wydajnej (O (n)) odrębnej operacji, która nie jest stanowa.Oto rozwiązanie wykorzystujące strumienie z Javą 8
Po prostu spójrz, czy częstotliwość tego obiektu jest więcej niż raz na liście. Następnie wywołaj .distinct (), aby mieć w wyniku tylko unikalne elementy
źródło
Collections::frequency
jest O (n). Aby znaleźć częstotliwość danego elementu, musi przejść przez całą kolekcję. I nazywamy to raz dla każdego elementu w kolekcji, co tworzy te fragmentyO(n^2)
. Zauważysz różnicę w każdym zbiorze obejmującą więcej niż kilka elementów. Nigdy nie użyłbym tego w rzeczywistym kodzie.podstawowe rozwiązanie java 8:
źródło
Oczywiście możesz z nimi zrobić, co chcesz (np. Umieścić w zestawie, aby uzyskać unikalną listę zduplikowanych wartości) zamiast drukowania ... Ma to również tę zaletę, że rejestruje lokalizację zduplikowanych elementów.
źródło
Używanie guawy w Javie 8
źródło
Działa to również:
źródło
Możesz użyć czegoś takiego:
źródło
int
jako typu zmiennej. Oznacza to, że dla każdej iteracji liczba całkowita jest rozpakowywana raz, a liczba int jest pakowana cztery razy!Rozwiązaniem mogą być jagnięciny
źródło
Użyj MultiMap, aby zapisać każdą wartość jako zestaw klucz / wartość. Następnie przejrzyj klucze i znajdź te z wieloma wartościami.
źródło
Jeśli używasz kolekcji Eclipse , zadziała to:
Aktualizacja: od Eclipse Collections 9.2 możesz teraz używać
selectDuplicates
Aby to osiągnąć, możesz również użyć kolekcji prymitywnych:
Uwaga: jestem promotorem Eclipse Collections.
źródło
źródło
Podobne do niektórych odpowiedzi tutaj, ale jeśli chcesz znaleźć duplikaty na podstawie jakiejś właściwości:
źródło
utwórz
Map<Integer,Integer>
, iteruj listę, jeśli element jest na mapie, zwiększ jego wartość, w przeciwnym razie dodaj go do mapy za pomocą klucza = 1iteruj mapę i dodaj do list wszystkie elementy za pomocą klucza> = 2
źródło
Kompaktowa uogólniona wersja najlepszej odpowiedzi, dodano również pusty czek i wstępnie przydzielony rozmiar zestawu:
źródło
tempSet
with tylkolistSize
wtedy, gdy jest to konieczne. To drobna optymalizacja, ale mi się podoba.Wziąłem odpowiedź Sebastiana i dodałem do niej keyExtractor -
źródło
Oto bezpieczna dla wątków alternatywa:
źródło
Spróbuj tego, aby znaleźć duplikaty pozycji na liście:
źródło
Powinno to działać w przypadku posortowanych i nieposortowanych.
źródło
To problem, w którym błyszczą techniki funkcjonalne. Na przykład poniższe rozwiązanie F # jest bardziej przejrzyste i mniej podatne na błędy niż najlepsze imperatywne rozwiązanie Java (i pracuję codziennie zarówno z Javą, jak i F #).
Oczywiście to pytanie dotyczy Javy. Dlatego proponuję przyjęcie biblioteki, która wprowadza funkcje funkcjonalne do Javy. Na przykład można to rozwiązać za pomocą mojej własnej biblioteki w następujący sposób (i jest kilka innych wartych obejrzenia):
źródło
źródło
źródło
To byłaby dobra metoda znajdowania zduplikowanych wartości bez używania Set.
Powiedzmy, że potrzebujesz metody, która zwraca odrębną listę, tj. Jeśli przekażesz listę, na której elementy występują więcej niż raz, otrzymasz listę z różnymi elementami.
źródło
I wersja, która używa
commons-collections
CollectionUtils.getCardinalityMap
metodę:`` ''
źródło
A co z tym kodem -
źródło
na wszelki wypadek dla tych, które również chcą uwzględnić zarówno duplikaty, jak i nie duplikaty. w zasadzie odpowiedź jest podobna do poprawnej odpowiedzi, ale zamiast wracać z, jeśli nie części, zwracasz inną część
użyj tego kodu (zmień na typ, który potrzebujesz)
źródło
Bardziej ogólna metoda jako wariant https://stackoverflow.com/a/52296246
źródło
Jeśli znasz maksymalną wartość (na przykład <10000), możesz poświęcić miejsce na rzecz prędkości. Nie pamiętam dokładnej nazwy tej techniki.
pseudo kod:
źródło
Po prostu spróbuj tego:
Przykład, jeśli wartości listy to: [1, 2, 3, 4, 5, 6, 4, 3, 7, 8] zduplikowany element [3, 4].
źródło