Bagaimana cara mengurutkan HashSet?


106

Untuk daftar, kami menggunakan Collections.sort(List)metode. Bagaimana jika kita ingin mengurutkan HashSet?


20
A HashSetadalah koleksi yang tidak diurutkan.
Alexis C.

2
Anda tidak bisa, karena a Settidak memiliki metode akses acak (yaitu, .get()elemen pada indeks tertentu), yang pada dasarnya diperlukan untuk algoritme sortir;)
fge

3
Anda dapat mengonversinya menjadi daftar terlebih dahulu lalu mengurutkan jika Anda perlu mengurutkan
demongolem

Anda tidak bisa karena HashSettidak memiliki urutan yang ditentukan. Pertanyaan Anda mengandung kontradiksi dalam istilah.
Marquis dari Lorne

1
gunakan TreeSet dan jika Anda tidak dapat mengontrol sumber, lihat konversi penggunaan di sini stackoverflow.com/a/52987487/5153955
Tenflex

Jawaban:


114

HashSet tidak menjamin urutan elemen apa pun. Jika Anda membutuhkan jaminan ini, pertimbangkan untuk menggunakan TreeSet untuk menampung elemen Anda.

Namun jika Anda hanya ingin elemen Anda disortir untuk kejadian yang satu ini, maka buat sementara saja Daftar dan urutkan:

Set<?> yourHashSet = new HashSet<>();

...

List<?> sortedList = new ArrayList<>(yourHashSet);
Collections.sort(sortedList);

1
Juga, jika Anda menggunakan koleksi Strings, makaList<String> sortedList = new ArrayList<String>(yourHashSet);
wisbucky

65

Tambahkan semua objek Anda ke TreeSet, Anda akan mendapatkan Set yang diurutkan. Di bawah ini adalah contoh mentahnya.

HashSet myHashSet = new HashSet();
myHashSet.add(1);
myHashSet.add(23);
myHashSet.add(45);
myHashSet.add(12);

TreeSet myTreeSet = new TreeSet();
myTreeSet.addAll(myHashSet);
System.out.println(myTreeSet); // Prints [1, 12, 23, 45]

2
Dengan menggunakan TreeSet myTreeSet = new TreeSet(myHashSet);Anda dapat menghindari menambahkan semua elemen ke Treeset lagi.
Mounika

17

Anda dapat menggunakan TreeSet sebagai gantinya.


1
Menempatkan elemen saja tidak akan memberikan fleksibilitas pengurutan pada urutan apa pun dengan elemen apa pun di dalamnya. Solusi di atas bisa.
Jess

16

Cara Java 8 untuk mengurutkannya adalah:

fooHashSet.stream()
  .sorted(Comparator.comparing(Foo::getSize)) //comparator - how you want to sort it
  .collect(Collectors.toList()); //collector - what you want to collect it to

* Foo::getSizeIni adalah contoh bagaimana mengurutkan HashSet dari YourItem secara alami berdasarkan ukuran.

* Collectors.toList()akan mengumpulkan hasil pengurutan ke dalam Daftar yang akan Anda perlukan untuk menangkapnyaList<Foo> sortedListOfFoo =


Bisakah Anda, Tambahkan logika untuk mengurutkannya dalam urutan tertentu?
Jess

@Jess saya tidak tahu apa urutan khusus untuk Anda Jess, Anda dapat mengurutkan sesuai keinginan menggunakan komparator.
LazerBanana

Maksud saya, bagaimana mendefinisikan Ascending atau Descending
Jess

14

Gunakan java.util.TreeSetsebagai objek sebenarnya. Saat Anda mengulang koleksi ini, nilainya kembali dalam urutan yang ditentukan dengan baik.

Jika Anda menggunakan java.util.HashSetmaka urutannya tergantung pada fungsi hash internal yang hampir pasti bukan leksikografik (berdasarkan konten).


Mengapa Anda berasumsi bahwa mereka menyimpan Stringnilai?
Sotirios Delimanolis

Saya tidak berpikir, mungkin penggunaan leksografik saya tidak tepat ;-)
P45 Imminent

3
Itu sangat salah. Itu tidak menyimpan kunci dalam urutan leksografik (sp?). Ia menggunakan pengurutan alami mereka (yang bergantung pada Comparableantarmuka yang diimplementasikan oleh tombol) atau menggunakan yang disediakan Comparator.
Sotirios Delimanolis

Saya sudah mengedit. Lebih baik menurut Anda, atau haruskah saya menghapus jawabannya?
P45 Segera

1
Jika Anda memindahkan HashSetke TreeSet, kelas Anda harus mengimplementasikan Comparableantarmuka atau menyediakan kustom Comparator. Jika tidak, karena Anda tidak dapat mengurutkan HashSet, cukup ubah menjadi Listdan urutkan.
Luiggi Mendoza

5

Anda dapat menggunakan kolektor Java 8 dan TreeSet

list.stream().collect(Collectors.toCollection(TreeSet::new))


new TreeSet<>(hashSet)lebih ringkas dan mungkin lebih efisien.
devconsole

4

Anda dapat menggunakan TreeSet seperti yang disebutkan dalam jawaban lain.

Berikut sedikit penjelasan tentang cara menggunakannya:

TreeSet<String> ts = new TreeSet<String>();
ts.add("b1");
ts.add("b3");
ts.add("b2");
ts.add("a1");
ts.add("a2");
System.out.println(ts);
for (String s: ts)
    System.out.println(s);

Keluaran:

[a1, a2, a3, a4, a5]
a1
a2
b1
b2
b3

4

Elemen di HashSet tidak dapat diurutkan. Setiap kali Anda memasukkan elemen ke dalam HashSet, itu dapat mengacaukan urutan keseluruhan set. Memang sengaja didesain seperti itu untuk performa. Jika Anda tidak peduli dengan pesanan, HashSet akan menjadi perangkat yang paling efisien untuk penyisipan dan pencarian cepat.

TreeSet akan mengurutkan semua elemen secara otomatis setiap kali Anda memasukkan elemen.

Mungkin, yang Anda coba lakukan adalah menyortir sekali saja. Dalam hal ini, TreeSet bukanlah pilihan terbaik karena ia perlu menentukan penempatan elemen yang baru ditambahkan setiap saat.

Solusi paling efisien adalah dengan menggunakan ArrayList. Buat daftar baru dan tambahkan semua elemen lalu urutkan sekali. Jika Anda hanya ingin mempertahankan elemen unik (hapus semua duplikat seperti yang dilakukan set, kemudian masukkan daftar ke dalam LinkedHashSet, itu akan mempertahankan urutan yang telah Anda urutkan)

List<Integer> list = new ArrayList<>();
list.add(6);
list.add(4);
list.add(4);
list.add(5);
Collections.sort(list);
Set<Integer> unique = new LinkedHashSet<>(list); // 4 5 6
// The above line is not copying the objects! It only copies references.

Sekarang, Anda telah mendapatkan kumpulan yang diurutkan jika Anda menginginkannya dalam bentuk daftar lalu mengubahnya menjadi daftar.


3

Berdasarkan jawaban yang diberikan oleh @LazerBanana saya akan memberikan contoh Set saya sendiri yang diurutkan berdasarkan Id Objek:

Set<Clazz> yourSet = [...];

yourSet.stream().sorted(new Comparator<Clazz>() {
    @Override
    public int compare(Clazz o1, Clazz o2) {
        return o1.getId().compareTo(o2.getId());
    }
}).collect(Collectors.toList()); // Returns the sorted List (using toSet() wont work)

3

Untuk berjaga-jaga jika Anda tidak ingin menggunakan, TreeSetAnda dapat mencoba ini.

set = set.stream().sorted().collect(Collectors.toCollection(LinkedHashSet::new));

2

Menurut pendapat saya, jawaban LazerBanana haruslah jawaban teratas & diterima karena semua jawaban lain yang menunjuk ke java.util.TreeSet(atau pertama-tama konversikan ke daftar lalu panggil Collections.sort(...)di daftar yang dikonversi) tidak repot-repot bertanya OP sebagai objek apa yang Anda HashSetmiliki yaitu jika elemen-elemen tersebut memiliki tatanan alami yang telah ditentukan sebelumnya atau tidak & itu bukan pertanyaan opsional tetapi pertanyaan wajib.

Anda tidak bisa masuk & mulai memasukkan HashSetelemen Anda ke dalam TreeSettipe elemen jika belum mengimplementasikan Comparableantarmuka atau jika Anda tidak secara eksplisit meneruskan Comparatorke TreeSetkonstruktor.

Dari TreeSetJavaDoc,

Membuat kumpulan pohon baru yang kosong, diurutkan menurut urutan alami elemennya. Semua elemen yang dimasukkan ke dalam himpunan harus mengimplementasikan antarmuka Comparable. Lebih lanjut, semua elemen tersebut harus saling sebanding: e1.compareTo (e2) tidak boleh menampilkan ClassCastException untuk elemen e1 dan e2 dalam himpunan. Jika pengguna mencoba menambahkan elemen ke set yang melanggar batasan ini (misalnya, pengguna mencoba menambahkan elemen string ke set yang elemennya bilangan bulat), panggilan add akan memunculkan ClassCastException.

Itulah mengapa hanya semua jawaban berbasis aliran Java8 - di mana Anda menentukan pembanding Anda di tempat - hanya masuk akal karena menerapkan perbandingan di POJO menjadi opsional. Programmer mendefinisikan pembanding jika diperlukan. Mencoba mengumpulkan TreeSettanpa menanyakan pertanyaan mendasar ini juga salah (jawaban Ninja). Mengasumsikan tipe objek menjadi Stringatau Integerjuga salah.

Karena itu, masalah lain seperti,

  1. Kinerja Penyortiran
  2. Memory Foot Print (mempertahankan set asli dan membuat set baru yang disortir setiap kali penyortiran selesai atau ingin mengurutkan set di - tempat dll)

harus menjadi poin relevan lainnya juga. Hanya menunjuk ke API seharusnya bukan hanya niat.

Karena set Asli sudah berisi hanya elemen unik & batasan itu juga dipertahankan oleh set yang diurutkan sehingga set asli perlu dihapus dari memori karena data diduplikasi.


1
1. Add all set element in list -> al.addAll(s);
2. Sort all the elements in list using -> Collections.sort(al);


 public class SortSetProblem {
 public static void main(String[] args) {
    ArrayList<String> al = new ArrayList();
    Set<String> s = new HashSet<>();
    s.add("ved");
    s.add("prakash");
    s.add("sharma");
    s.add("apple");
    s.add("ved");
    s.add("banana");
    System.out.println("Before Sorting");
    for (String s1 : s) {
        System.out.print("  " + s1);
    }

    System.out.println("After Sorting");
    al.addAll(s);
    Collections.sort(al);
    for (String set : al) {
        System.out.print(" " + set);
    }
  }
 }

masukan - ved prakash sharma apple ved banana

Hasil - pisang apel prakash sharma ved


1

Jika Anda ingin bagian akhir Collectiondalam bentuk Setdan jika Anda ingin menentukan sendiri natural orderdaripada yang TreeSetmaka -

1. Ubah HashSetmenjadi List
2. Urutkan sesuai keinginan Listmenggunakan Comparator
3. Ubah kembali Listmenjadi LinkedHashSetuntuk mempertahankan urutan
4. Tampilkan LinkedHashSet

Program sampel -

package demo31;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class App26 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        addElements(set);
        List<String> list = new LinkedList<>();
        list = convertToList(set);
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                int flag = s2.length() - s1.length();
                if(flag != 0) {
                    return flag;
                } else {
                    return -s1.compareTo(s2);
                }
            }
        });
        Set<String> set2 = new LinkedHashSet<>();
        set2 = convertToSet(list);
        displayElements(set2);
    }
    public static void addElements(Set<String> set) {
        set.add("Hippopotamus");
        set.add("Rhinocerous");
        set.add("Zebra");
        set.add("Tiger");
        set.add("Giraffe");
        set.add("Cheetah");
        set.add("Wolf");
        set.add("Fox");
        set.add("Dog");
        set.add("Cat");
    }
    public static List<String> convertToList(Set<String> set) {
        List<String> list = new LinkedList<>();
        for(String element: set) {
            list.add(element);
        }
        return list;
    }
    public static Set<String> convertToSet(List<String> list) {
        Set<String> set = new LinkedHashSet<>();
        for(String element: list) {
            set.add(element);
        }
        return set;
    }
    public static void displayElements(Set<String> set) {
        System.out.println(set);
    }
}

Keluaran -

[Hippopotamus, Rhinocerous, Giraffe, Cheetah, Zebra, Tiger, Wolf, Fox, Dog, Cat]

Di sini koleksi telah diurutkan sebagai -

Pertama - Urutan Stringpanjang
menurun Kedua - Urutan Stringhierarki abjad menurun


0

Anda dapat melakukannya dengan cara berikut:

Metode 1:

  1. Buat daftar dan simpan semua nilai hash ke dalamnya
  2. urutkan daftar menggunakan Collections.sort ()
  3. Simpan daftar kembali ke LinkedHashSet karena ini mempertahankan urutan penyisipan

Metode 2:

  • Buat treeSet dan simpan semua nilai ke dalamnya.

Metode 2 lebih disukai karena metode lain menghabiskan banyak waktu untuk mentransfer data bolak-balik antara hashset dan daftar.


0

Kami tidak dapat memutuskan bahwa elemen dari sebuah HashSet akan diurutkan secara otomatis. Tapi kita bisa mengurutkannya dengan mengubahnya menjadi TreeSet atau List seperti ArrayList atau LinkedList dll.

// Create a TreeSet object of class E
TreeSet<E> ts = new TreeSet<E> ();

// Convert your HashSet into TreeSet
ts.addAll(yourHashSet);

System.out.println(ts.toString() + "\t Sorted Automatically");

0

Anda dapat menggunakan perpustakaan jambu biji untuk hal yang sama

Set<String> sortedSet = FluentIterable.from(myHashSet).toSortedSet(new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        // descending order of relevance
        //required code
    }
});


0

Anda dapat membungkusnya dalam TreeSet seperti ini:

Set mySet = new HashSet();
mySet.add(4);
mySet.add(5);
mySet.add(3);
mySet.add(1);
System.out.println("mySet items "+ mySet);   

TreeSet treeSet = new TreeSet(mySet);   
System.out.println("treeSet items "+ treeSet);   

keluaran:
item mySet [1, 3, 4, 5]
item treeSet [1, 3, 4, 5]

Set mySet = new HashSet();
mySet.add("five");
mySet.add("elf");
mySet.add("four");
mySet.add("six");
mySet.add("two");
System.out.println("mySet items "+ mySet);

TreeSet treeSet = new TreeSet(mySet);
System.out.println("treeSet items "+ treeSet);

keluaran:
item mySet [enam, empat, lima, dua, elf]
item treeSet [elf, lima, empat, enam, dua]

persyaratan untuk metode ini adalah bahwa objek set / list harus sebanding (mengimplementasikan antarmuka Comparable)


-4

Perintah sederhana ini melakukan trik untuk saya:

myHashSet.toList.sorted

Saya menggunakan ini dalam pernyataan cetak, jadi jika Anda perlu benar-benar mempertahankan pemesanan, Anda mungkin perlu menggunakan TreeSets atau struktur lain yang diusulkan di utas ini.


1
Saya tidak melihat di mana HashSet atau Set memiliki metode toList.
Thomas Eizinger

1
Sepertinya Scala bagi saya, yang sayangnya tidak menyelesaikan masalah di Java.
Roberto

Metode toList, Bagaimana mungkin?
Ved Prakash
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.