Java Set tetap mempertahankan?

179

Apakah Java Set mempertahankan pesanan? Suatu metode mengembalikan Set kepada saya dan konon datanya dipesan tetapi iterasi pada Set tersebut, datanya tidak diurutkan. Apakah ada cara yang lebih baik untuk mengelola ini? Apakah metode ini perlu diubah untuk mengembalikan sesuatu selain dari Set?

pengguna840930
sumber
3
"Elemen dikembalikan tanpa urutan tertentu (kecuali set ini adalah turunan dari beberapa kelas yang memberikan jaminan)." adalah apa metode iterator untuk satu set berkata. ditemukan di sini
keyser

Jawaban:

256

The Setantarmuka tidak menyediakan jaminan pemesanan.

Sub-interface-nya SortedSetmewakili satu set yang diurutkan berdasarkan beberapa kriteria. Di Jawa 6, ada dua kontainer standar yang diterapkan SortedSet. Mereka TreeSetdan ConcurrentSkipListSet.

Selain SortedSetantarmuka, ada juga LinkedHashSetkelasnya. Itu mengingat urutan elemen dimasukkan ke set, dan mengembalikan elemen dalam urutan itu.

NPE
sumber
21
Selanjutnya, karena hashing String yang berbeda di Java 8, pemesanan default (tidak diurutkan) di Sets dan Maps akan berubah. Jika Anda mengandalkan pemesanan yang tidak disortir, kode Anda akan berperilaku berbeda di bawah Java 8.
rustyx
Saya mendapatkan bahwa kelas tidak memesan adalah normal, tetapi perilaku yang saya harapkan adalah meninggalkan mereka karena mereka diperkenalkan dan tidak mengacaukan pesanan, sebaliknya itu hanya mengocok elemen setiap kali satu agregat. Solusi Anda tidak akan layu karena saya harus menerapkan seluruh struktur agar dapat diurutkan DENGAN CARA SAMA mereka diperkenalkan: S
White_King
@White_King: Satu set adalah konsep matematika yang tidak mengandung pengertian "urutan penyisipan" sehingga masuk akal bagi antarmuka Java untuk mengikuti konvensi-konvensinya. Ada set yang dipesan tetapi urutannya ditentukan oleh relasi (pembanding di Jawa), yang lagi-lagi cocok dengan definisi dalam teori himpunan dengan definisi di Jawa. Harapan Anda tentang hal itu menjaga urutan penyisipan mungkin berasal dari daftar tetapi set bukan daftar.
Konrad Höffner
103

LinkedHashSet adalah apa yang Anda butuhkan.

xiaofeng.li
sumber
43
A Listbukan a Set(itu tidak menjamin keunikan keanggotaan).
Penebusan Terbatas
10
Dalam banyak kasus unik bisnis, Daftar tidak dapat digunakan hanya untuk mempertahankan pesanan alih-alih Ditetapkan. LinkedHashSet mempertahankan ketertiban dan toko yang unik.
gubs
18

Seperti banyak anggota menyarankan gunakan LinkedHashSet untuk mempertahankan urutan koleksi. Anda dapat membungkus set Anda menggunakan implementasi ini.

Implementasi SortedSet dapat digunakan untuk pesanan yang diurutkan tetapi untuk tujuan Anda gunakan LinkedHashSet .

Juga dari dokumen,

"Implementasi ini menyelamatkan klien-kliennya dari pemesanan yang tidak ditentukan, umumnya kacau yang disediakan oleh HashSet, tanpa menimbulkan biaya yang meningkat terkait dengan TreeSet. Hal ini dapat digunakan untuk menghasilkan salinan set yang memiliki urutan yang sama seperti aslinya, terlepas dari aslinya implementasi set: "

Sumber: http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html

Lakshman
sumber
9

Set hanyalah sebuah antarmuka. Untuk mempertahankan pesanan, Anda harus menggunakan implementasi spesifik antarmuka itu dan sub-antarmuka SortedSet, misalnya TreeSet atau LinkedHashSet. Anda dapat membungkus Set Anda dengan cara ini:

Set myOrderedSet = new LinkedHashSet(mySet);
javatutorial
sumber
7

Berikut ini adalah ringkasan singkat dari karakteristik urutan Setimplementasi standar yang tersedia di Jawa:

  1. menjaga urutan penyisipan: LinkedHashSet dan CopyOnWriteArraySet (thread-safe)
  2. menjaga item diurutkan dalam set: TreeSet , EnumSet (khusus untuk enums) dan ConcurrentSkipListSet (aman untuk thread)
  3. tidak menyimpan item dalam urutan tertentu: HashSet (yang Anda coba)

Untuk kasus spesifik Anda, Anda dapat mengurutkan item terlebih dahulu dan kemudian menggunakan salah satu dari 1 atau 2 (kemungkinan besar LinkedHashSetatau TreeSet). Atau sebagai alternatif dan lebih efisien , Anda bisa menambahkan data yang tidak disortir ke TreeSetyang akan mengurus penyortiran secara otomatis untuk Anda.

assylias
sumber
7

Untuk mempertahankan pesanan, gunakan Listatau LinkedHashSet.

JHS
sumber
1
Ini LinkedHashSet, tidak ... Map.
Marko Topolnik
Saya perlu Set bukan Daftar, saya perlu Set yang JUGA mempertahankan urutan injeksi objek saya kira
White_King
5

LinkedHashSet adalah versi HashSet yang diurutkan yang memelihara Daftar yang ditautkan ganda di semua elemen. Gunakan kelas ini alih-alih HashSet saat Anda peduli dengan urutan iterasi.

Danail Tsvetanov
sumber
3

Dari javadoc untuk Set.iterator():

Mengembalikan iterator atas elemen dalam set ini. Elemen-elemen dikembalikan tanpa urutan tertentu (kecuali set ini adalah turunan dari beberapa kelas yang memberikan jaminan).

Dan, seperti yang telah dinyatakan oleh shuuchan , a TreeSetadalah implementasi dari Setyang memiliki jaminan:

Elemen-elemen dipesan menggunakan pengurutan alami mereka, atau oleh Pembanding yang disediakan pada waktu pembuatan yang ditetapkan, tergantung pada konstruktor mana yang digunakan.

hmjd
sumber
3

Biasanya yang diatur tidak menjaga urutan, seperti HashSet agar dapat dengan cepat menemukan emelent, tetapi Anda dapat mencoba LinkedHashSet itu akan menjaga urutan yang Anda masukkan.

pengguna1335794
sumber
1

Ada 2 hal berbeda.

  1. Urutkan elemen dalam satu set. Untuk itu kami memiliki SortedSet dan implementasi serupa.
  2. Pertahankan urutan penyisipan dalam satu set. Untuk itulah LinkedHashSet dan CopyOnWriteArraySet (thread-safe) dapat digunakan.
Aruna
sumber
0

Set interface itu sendiri tidak menetapkan urutan tertentu. Namun, SortedSet melakukannya.

Jens Borgland
sumber
-2

Hanya SortedSetdapat melakukan pemesananSet


sumber
Pertanyaannya adalah tentang mempertahankan urutan penyisipan (yang kebetulan disortir).
assylias