Czy zestaw Java zachowuje porządek?


179

Czy zestaw Java zachowuje kolejność? Metoda zwraca do mnie zestaw i przypuszczalnie dane są uporządkowane, ale iterując po zestawie, dane są nieuporządkowane. Czy jest lepszy sposób, aby to zrobić? Czy należy zmienić metodę, aby zwrócić coś innego niż zestaw?


3
„Elementy są zwracane w dowolnej kolejności (chyba że ten zestaw jest instancją jakiejś klasy, która daje gwarancję)”. tak mówi metoda iteratora dla zbioru. znalezione tutaj
keyser

Odpowiedzi:


256

SetInterfejs nie udziela żadnych gwarancji zamówieniu.

Jego interfejs podrzędny SortedSetreprezentuje zestaw posortowany według pewnego kryterium. W Javie 6 są dwa standardowe kontenery, które implementują SortedSet. Są TreeSeti ConcurrentSkipListSet.

Oprócz SortedSetinterfejsu jest też LinkedHashSetklasa. Zapamiętuje kolejność, w jakiej elementy zostały wstawione do zestawu i zwraca jego elementy w tej kolejności.


21
Co więcej, ze względu na różne haszowanie ciągów znaków w Javie 8, zmieni się domyślna (nieposortowana) kolejność w zestawach i mapach. Jeśli polegasz na niesortowanych zamówieniach, Twój kod będzie zachowywał się inaczej w Javie 8.
rustyx

Rozumiem, że klasa nie uporządkowana jest normalna, ale zachowanie, którego się spodziewałem, polegało na pozostawieniu ich w takiej postaci, w jakiej zostały wprowadzone, i nie zepsuciu kolejności, zamiast tego polega na tasowaniu elementów za każdym razem, gdy jeden jest agregowany. Twoje rozwiązanie nie jest optymalne, ponieważ wtedy będę musiał zaimplementować całą strukturę, aby zostały posortowane W TAKI SPOSÓB, w jaki zostały wprowadzone: S
White_King

@White_King: Zestaw jest matematyczną koncepcją, która nie zawiera pojęcia „kolejność wstawiania”, więc sensowne jest, aby interfejs Java działał zgodnie z jego konwencjami. Istnieją uporządkowane zbiory, ale kolejność jest określona przez relację (komparator w Javie), ponownie dopasowując definicję w teorii mnogości do definicji w Javie. Twoje oczekiwanie, że utrzyma kolejność reklam, prawdopodobnie pochodzi z list, ale zestawy nie są listami.
Konrad Höffner

103

LinkedHashSet jest tym, czego potrzebujesz.


43
A Listnie jest Set(nie gwarantuje to niepowtarzalności członkostwa).
Limited Atonement

10
W wielu wyjątkowych sytuacjach biznesowych Lista nie może być używana tylko do zachowania porządku zamiast Set. LinkedHashSet utrzymuje porządek i przechowuje unikalne.
gubs

18

Jak wielu członków sugerowało, użyj LinkedHashSet, aby zachować kolejność kolekcji. Możesz opakować swój zestaw za pomocą tej implementacji.

Implementacja SortedSet może służyć do sortowania kolejności, ale w tym celu użyj LinkedHashSet .

Również z dokumentacji,

„Ta implementacja oszczędza klientom nieokreślonego, generalnie chaotycznego porządkowania zapewnianego przez HashSet, bez ponoszenia zwiększonych kosztów związanych z TreeSet. Może być wykorzystana do stworzenia kopii zestawu, który ma taką samą kolejność jak oryginał, niezależnie od oryginału wykonanie zestawu: „

Źródło: http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html


9

Zestaw to tylko interfejs. Aby zachować porządek, musisz użyć określonej implementacji tego interfejsu i podinterfejsu SortedSet, na przykład TreeSet lub LinkedHashSet. Możesz opakować swój zestaw w ten sposób:

Set myOrderedSet = new LinkedHashSet(mySet);

7

Oto krótkie podsumowanie charakterystyki kolejności standardowych Setimplementacji dostępnych w Javie:

  1. zachowaj kolejność reklamową : LinkedHashSet i CopyOnWriteArraySet (bezpieczne wątkowo )
  2. utrzymuj elementy posortowane w zestawie: TreeSet , EnumSet (specyficzne dla wyliczeń ) i ConcurrentSkipListSet (bezpieczne wątkowo )
  3. nie utrzymuje pozycji w określonej kolejności: HashSet (ten, którego próbowałeś)

W swoim konkretnym przypadku możesz najpierw posortować elementy, a następnie użyć jednego z 1 lub 2 (najprawdopodobniej LinkedHashSetlub TreeSet). Lub alternatywnie i wydajniej , możesz po prostu dodać nieposortowane dane do pliku, TreeSetktóry automatycznie zajmie się sortowaniem.


7

Aby zachować zamówienie, użyj Listlub a LinkedHashSet.


1
To LinkedHashSetnie ... Map.
Marko Topolnik

Potrzebuję zestawu, a nie listy, potrzebuję zestawu, który RÓWNIEŻ zachowuje kolejność wstrzykiwania obiektów, jak sądzę
White_King

5

LinkedHashSet to uporządkowana wersja HashSet, która utrzymuje podwójnie połączoną listę wszystkich elementów. Użyj tej klasy zamiast HashSet, jeśli zależy Ci na kolejności iteracji.


3

Z javadoc dla Set.iterator():

Zwraca iterator dla elementów w tym zestawie. Elementy są zwracane w dowolnej kolejności (chyba że ten zestaw jest instancją jakiejś klasy, która daje gwarancję).

I, jak już powiedział shuuchan , a TreeSetjest implementacją, Setktóra ma gwarantowaną kolejność:

Elementy są porządkowane przy użyciu ich naturalnego porządku lub przez Komparator dostarczany w określonym czasie tworzenia, w zależności od używanego konstruktora.


3

Zwykle set nie zachowuje kolejności, takiej jak HashSet, aby szybko znaleźć emelent, ale możesz wypróbować LinkedHashSet, który zachowa kolejność, którą złożyłeś.


1

Są 2 różne rzeczy.

  1. Posortuj elementy w zestawie. Dla których mamy SortedSet i podobne implementacje.
  2. Zachowaj kolejność reklam w zestawie. W przypadku których można użyć LinkedHashSet i CopyOnWriteArraySet (bezpieczne wątkowo).



-2

Tylko SortedSetmoże zrobić porządek zSet


Pytanie dotyczy zachowania zamówienia reklamowego (które jest posortowane).
assylias
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.