Treeeset mendukung dua metode penyortiran: penyortiran alami dan penyortiran khusus. Treeeset menggunakan penyortiran alami secara default.
1. Penyortiran alami
TreeSet akan memanggil metode compareTo (objek OBJ) dari elemen pengumpulan untuk membandingkan hubungan ukuran antara elemen, dan kemudian mengatur elemen pengumpulan dalam urutan naik. (Presponse untuk perbandingan: Kedua objek memiliki tipe yang sama).
Java menyediakan antarmuka yang sebanding, yang mendefinisikan metode compareTo (objek OBJ), yang mengembalikan nilai integer. Ketika suatu objek memanggil metode untuk membandingkan dengan objek lain, misalnya obj1.comparto (OBJ2), jika metode ini mengembalikan 0, itu berarti bahwa kedua objek tersebut sama; OBJ2; jika metode ini dikembalikan bilangan bulat negatif berarti OBJ1 kurang dari OBJ2.
Kelas Java umum menerapkan antarmuka yang sebanding dan memberikan standar untuk ukuran komparatif. Kelas umum yang menerapkan antarmuka yang sebanding:
Jika Anda mencoba menambahkan objek ke treeset, kelas objek harus mengimplementasikan antarmuka yang sebanding.
Kesalahan akan dilaporkan dalam program berikut:
class err {} kelas public testtreeseTerror {public static void main (string [] args) {treeset ts = new treeset (); Tambahkan (ERR ());}}menjelaskan:
Program di atas mencoba untuk menambahkan 2 objek erat ke koleksi TreeSet. dari objek) metode dibandingkan dengan elemen lain dalam koleksi - jika kelas yang sesuai tidak mengimplementasikan antarmuka yang sebanding, ClassCastException akan dinaikkan. Selain itu, ketika mencoba menghapus elemen pertama dari elemen dari Treeset, pengecualian ClassCastException masih akan dinaikkan.
Saat membandingkan objek menggunakan metode compareTo (objek OBJ), jenis objek yang dibandingkan OBJ perlu dilemparkan ke jenis yang sama, karena hanya dua contoh dari kelas yang sama yang dapat membandingkan ukurannya. Artinya, objek yang ditambahkan ke Treeset harus dari kelas yang sama, jika tidak, ClassCastException akan dinaikkan. Misalnya, saat menambahkan objek string ke treeset, operasi ini benar -benar normal. Saat menambahkan objek tanggal kedua, TreeSet akan memanggil metode compareTo (objek OBJ) objek untuk membandingkan dengan elemen lain dalam koleksi, dan program akan melempar pengecualian saat ini.
Dalam pemrograman yang sebenarnya, pemrogram dapat menentukan kelas mereka sendiri untuk menambahkan beberapa jenis objek ke TreeSet, dengan ketentuan bahwa kelas yang ditentukan pengguna mengimplementasikan antarmuka yang sebanding. . Mengubah. Namun, ketika mengoperasikan data pengumpulan di TreeSet, pengecualian ClassCastExceptio masih akan terjadi untuk elemen -elemen dari berbagai jenis. (Anda akan mengerti setelah membaca dengan cermat)
Ketika suatu objek ditambahkan ke koleksi TreeSet, TreeSet menyebut metode compareto objek (objek OBJ) untuk membandingkan ukuran dengan objek lain dalam wadah, dan kemudian menentukan lokasi penyimpanannya berdasarkan algoritma pohon merah dan hitam. Jika dua objek dibandingkan secara merata oleh Compareto (objek OBJ), Treeset menganggap mereka menyimpan lokasi yang sama.
Untuk koleksi TreeSet, kriteria untuk menentukan bahwa dua objek tidak sama adalah: Dua objek mengembalikan false melalui perbandingan metode yang sama, atau perbandingan compareto (objek obj) tidak mengembalikan 0 - bahkan jika kedua objek tersebut adalah objek yang sama, pohon mereka juga akan diproses sebagai dua objek.
Program berikut menunjukkan:
// Kelas Z, ditulis ulang metode yang sama, selalu mengembalikan False, // Metode CompareTo (Object Obj), selalu mengembalikan integer positif kelas Z yang sebanding {int usia; } public boolean sama (objek obj) {return false; Z z1 = New Z (6); set); Melihat juga 9 System.out.println (((Z) (set.Last ())). Usia);Hasil menjalankan program:
BENAR
[Treeset.z@1FB8EE3, Treeset.z@1fb8ee3]
9
menjelaskan:
Objek yang sama ditambahkan dua kali dalam program, karena metode Equals () dari objek Z1 selalu mengembalikan false, dan metode compareTo (objek OBJ) selalu mengembalikan 1. Dengan cara ini, TreeSet akan berpikir bahwa objek Z1 berbeda dari dirinya sendiri, jadi tambahkan dua objek Z1 ke Treeset. Dua elemen yang disimpan oleh objek TreeSet sebenarnya adalah elemen yang sama. Oleh karena itu, setelah memodifikasi atribut usia dari elemen pertama dalam koleksi TreeSet, atribut usia elemen terakhir dalam koleksi TreeSet juga berubah.
Ringkasan : Ketika Anda perlu memasukkan objek ke dalam TreeSet, dan menulis ulang metode Equals () dari kelas yang sesuai dari objek, Anda harus memastikan bahwa metode ini memiliki hasil yang konsisten dengan metode compareTo (objek OBJ). Dua objek berlalu ketika perbandingan metode yang sama mengembalikan true, kedua objek harus mengembalikan 0 dengan membandingkan metode compareTo (objek OBJ).
Jika dua objek dibandingkan dengan metode yang setara, tetapi kedua objek dibandingkan dengan metode compareTo (objek OBJ) dan tidak mengembalikan 0, ini akan menyebabkan Treeset menyimpan kedua objek di lokasi yang berbeda, sehingga kedua objek itu bisa ditambahkan dengan sukses, yang sedikit berbeda dari aturan koleksi set.
Jika dua objek mengembalikan 0 dengan membandingkan metode compareTo (objek OBJ), tetapi mereka mengembalikan false dengan membandingkan metode yang sama: karena kedua objek tersebut sama -sama dibandingkan dengan membandingkan metode compareTo (objek OBJ), Treeset akan mencoba menyimpannya di dalam Lokasi yang sama, tetapi sebenarnya tidak berhasil (jika tidak, hanya akan ada satu objek yang tersisa), jadi lebih merepotkan untuk ditangani.
Jika objek yang dapat berubah ditambahkan ke treeset dan program selanjutnya memodifikasi sifat -sifat objek yang dapat berubah, menyebabkannya mengubah urutan ukuran dengan objek lain, tetapi TreeSet tidak akan menyesuaikan pesanan mereka lagi, dan bahkan dapat menyebabkannya disimpan Di TreeSet kedua objek ini, mereka mengembalikan true dengan membandingkan metode yang sama, dan metode compareTo (objek OBJ) mengembalikan 0.
Program berikut menunjukkan:
kelas r {int count; if (instance r) {r r = (r) obj; class testHashset2 {public static void main (string [] args) {hashset hs = new hashset (); R (9)); .iterator (); di None State System.out.println (HS); -3 R objek? " + Hs.contains (baru r (-3))); // output false system.out.println (" apakah hs berisi objek dengan jumlah 5? " + Hs.contains (r baru (baru 5)));Hasil menjalankan program:
[R (Hitung Atribut: -3), R (Hitung Atribut: -2), R (Hitung Atribut: 5), R (Hitung Atribut: 9)]
[R (Hitung Atribut: 20), R (Hitung Atribut: -2), R (Hitung Atribut: 5), R (Hitung Atribut: -2)]
[R (Hitung Atribut: 20), R (Hitung Atribut: -2), R (Hitung Atribut: 5), R (Hitung Atribut: -2)]
[R (Hitung Atribut: 20), R (Hitung Atribut: -2), R (Hitung Atribut: -2)]
menjelaskan:
Objek R dalam program di atas adalah penulisan ulang normal dari metode yang sama dan kelas metode yang sebanding. Anda dapat melihat bahwa output pertama dari program ini diatur secara tertib. Ketika properti penghitungan objek R diubah, hasil output dari program juga berubah dan berisi elemen duplikat. Setelah sifat -sifat elemen variabel dalam koleksi TreeSet diubah, ketika objek dihapus dalam tampilan, Treeset akan gagal dihapus (bahkan elemen yang asli dalam koleksi belum dimodifikasi, tetapi elemen yang sama dengan yang dimodifikasi elemen tidak dapat dihapus).
Ketika objek R dengan -2, tidak ada elemen yang dihapus;
Ringkasan: Dengan hashset, itu akan sangat kompleks dan rentan kesalahan saat berhadapan dengan objek-objek ini. Untuk membuat program lebih kuat, disarankan agar hanya benda abadi ditempatkan di koleksi hashset dan treeset.
2. Penyortiran Kustom
Jenis TreeSet alami didasarkan pada ukuran elemen pengumpulan, dan Treeset mengaturnya dalam urutan naik. Jika Anda perlu menerapkan penyortiran khusus, seperti pesanan menurun, Anda dapat menggunakan antarmuka pembanding. Antarmuka ini berisi metode perbandingan int (t o1, t o2), yang digunakan untuk membandingkan ukuran O1 dan O2.
Jika Anda perlu menerapkan penyortiran yang disesuaikan, Anda perlu memberikan objek pembanding saat membuat objek pengumpulan TreeSet dan memberikan objek pembanding untuk bergaul dengan koleksi TreeSet, dan objek pembanding bertanggung jawab untuk logika penyortiran elemen pengumpulan.
Program berikut menunjukkan:
kelas m {int usia; main (string [] args) {treeset ts = treeset baru (pembanding baru () {public int perbandingan (objek o1, objek o2) {m m1 = (m) o1; m m2 = (m) o2; if (m1. usia> m2.age) {return -1; ts.add (m baru (-3));Hasil menjalankan program:
[M objek (Usia: 9), M objek (usia: 5), m objek (usia: -3)]
menjelaskan:
Program di atas menciptakan objek kelas internal anonim dari antarmuka pembanding, yang bertanggung jawab untuk penyortiran koleksi TS. Jadi ketika kami menambahkan objek M ke koleksi TS, tidak perlu kelas M untuk mengimplementasikan antarmuka yang sebanding, karena pada saat ini, TreeSet tidak perlu membandingkan ukuran melalui objek M, tetapi objek pembanding yang terkait dengan TreeSet bertanggung jawab atas penyortiran elemen pengumpulan. Saat menggunakan penyortiran khusus, TreeSet mengurutkan elemen pengumpulan terlepas dari ukuran elemen pengumpulan itu sendiri, tetapi objek pembanding bertanggung jawab atas aturan penyortiran elemen pengumpulan.