कैसे एक हैशसेट को सॉर्ट करें?


106

सूचियों के लिए, हम Collections.sort(List)विधि का उपयोग करते हैं । अगर हम छांटना चाहते हैं तो क्या होगा HashSet?


20
A HashSetएक अनियोजित संग्रह है।
एलेक्सिस सी।

2
आप नहीं कर सकते हैं, क्योंकि Setइसमें यादृच्छिक अभिगम विधियां नहीं हैं (यानी, .get()किसी दिए गए इंडेक्स में एक तत्व), जो मूल रूप से सॉर्ट एल्गोरिदम के लिए आवश्यक है;)
fge

3
आप इसे पहले एक सूची में बदल सकते हैं, फिर
छाँट

चूंकि आपके HashSetपास परिभाषित आदेश नहीं है। आपका प्रश्न शब्दों में विरोधाभास का प्रतीक है।
लोर्ने

जवाबों:


114

एक HashSet अपने तत्वों के किसी भी आदेश की गारंटी नहीं देता है। यदि आपको इस गारंटी की आवश्यकता है, तो अपने तत्वों को रखने के लिए ट्रीसेट का उपयोग करने पर विचार करें।

हालाँकि अगर आपको इस एक घटना के लिए अपने तत्वों को क्रमबद्ध करने की आवश्यकता है, तो बस अस्थायी रूप से एक सूची बनाएं और इसे क्रमबद्ध करें:

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

...

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

1
इसके अलावा, यदि आप स्ट्रिंग्स के संग्रह का उपयोग कर रहे हैं, तोList<String> sortedList = new ArrayList<String>(yourHashSet);
18'18

65

अपनी सभी वस्तुओं को इसमें जोड़ें TreeSet, आपको एक हल किया हुआ सेट मिलेगा। नीचे एक कच्चा उदाहरण है।

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
TreeSet myTreeSet = new TreeSet(myHashSet);आप का उपयोग करके आप सभी तत्वों को फिर से ट्रीसेट में जोड़ने से बच सकते हैं।
मौनिका

17

आप इसके बजाय ट्रीसेट का उपयोग कर सकते हैं ।


1
बस तत्वों को डालने से इसके अंदर किसी भी तत्व के साथ किसी भी क्रम पर छंटनी का लचीलापन नहीं मिलेगा। उपरोक्त उपाय करता है।
जेस

16

जावा 8 को छाँटने का तरीका यह होगा:

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::getSizeयह एक उदाहरण है कि कैसे YourItem के हैशसेट को स्वाभाविक रूप से आकार के आधार पर क्रमबद्ध किया जाए।

* Collectors.toList()एक सूची में छँटाई के परिणाम को इकट्ठा करने जा रहा है जिसे आपको इसके साथ कैप्चर करना होगाList<Foo> sortedListOfFoo =


क्या आप कृपया, इसे विशिष्ट क्रम में क्रमबद्ध करने के लिए तर्क जोड़ सकते हैं?
जेस

@ मुझे नहीं पता कि जेस के लिए आपके लिए क्या विशिष्ट आदेश है, आप इसे छाँट सकते हैं जैसा कि आप तुलनित्र का उपयोग करना चाहते हैं।
लेज़रबाना

मेरा मतलब है,
जेस

14

java.util.TreeSetवास्तविक वस्तु के रूप में उपयोग करें । जब आप इस संग्रह पर पुनरावृत्ति करते हैं, तो मान एक अच्छी तरह से परिभाषित क्रम में वापस आ जाते हैं।

यदि आप उपयोग करते हैं java.util.HashSetतो ऑर्डर एक आंतरिक हैश फ़ंक्शन पर निर्भर करता है जो लगभग निश्चित रूप से लेक्सिकोग्राफ़िक नहीं है (सामग्री के आधार पर)।


आप क्यों मान रहे हैं कि वे Stringमूल्यों को संग्रहीत करते हैं?
सोतिरियोस डेलिमोलिस

हालांकि मैं शायद लेक्सोग्राफ़िक का मेरा उपयोग नहीं कर रहा हूँ ;-)
P45

3
यह बहुत गलत है। यह लेक्सोग्राफ़िक (स्प?) क्रम में कुंजियाँ संग्रहीत नहीं करता है। यह या तो उनके प्राकृतिक ऑर्डरिंग का उपयोग करता है (जो कि Comparableइंटरफेस पर निर्भर करता है जो कुंजियां लागू होती हैं) या प्रदान किए गए का उपयोग करता है Comparator
सोतिरियोस डेलिमोलिस

मैंने संपादित किया है। बेहतर है कि आप सोचते हैं, या मुझे उत्तर हटाना चाहिए?
पी 45 इम्मानेंट

1
यदि आप एक HashSetको स्थानांतरित करते हैं TreeSet, तो आपकी कक्षा को Comparableइंटरफ़ेस लागू करना होगा या एक कस्टम प्रदान करना होगा Comparator। अन्यथा, चूंकि आप एक सॉर्ट नहीं कर सकते हैं HashSet, बस इसे एक में Listबदलें और इसे सॉर्ट करें।
लुइगी मेंडोज़ा

5

आप जावा 8 कलेक्टर और ट्रीसेट का उपयोग कर सकते हैं

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


new TreeSet<>(hashSet)अधिक संक्षिप्त है और शायद अधिक कुशल है।
devconsole

4

आप अन्य उत्तरों में बताए अनुसार ट्रीसेट का उपयोग कर सकते हैं।

यहां इसका उपयोग करने के बारे में थोड़ा और विस्तार दिया गया है:

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);

आउटपुट:

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

4

HashSet में तत्वों को सॉर्ट नहीं किया जा सकता है। जब भी आप तत्वों को हैशसेट में डालते हैं, तो यह पूरे सेट के क्रम को गड़बड़ कर सकता है। यह जानबूझकर प्रदर्शन के लिए डिज़ाइन किया गया है। जब आप ऑर्डर के बारे में परवाह नहीं करते हैं, तो हैशसेट तेजी से प्रविष्टि और खोज के लिए सबसे कुशल सेट होगा।

ट्रीसेट किसी भी तत्व को सम्मिलित करने पर हर बार स्वचालित रूप से सभी तत्वों को सॉर्ट करेगा।

शायद, आप जो करने की कोशिश कर रहे हैं वह सिर्फ एक बार छांटना है। उस मामले में, ट्रीसेट सबसे अच्छा विकल्प नहीं है, क्योंकि इसे हर समय नए जोड़े गए तत्वों को निर्धारित करने की आवश्यकता होती है।

ArrayList का उपयोग करने के लिए सबसे कुशल समाधान है। एक नई सूची बनाएं और सभी तत्वों को जोड़ें और फिर इसे एक बार सॉर्ट करें। यदि आप केवल अनन्य तत्वों को बनाए रखना चाहते हैं (सेट डुप्लिकेट की तरह सभी डुप्लिकेट को हटा दें, तो सूची को एक लिंक्डहैशसेट में डाल दें, यह आपके द्वारा पहले से ही क्रमबद्ध क्रम को बनाए रखेगा)

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.

अब, आप एक क्रमबद्ध सेट प्राप्त कर चुके हैं यदि आप इसे सूची रूप में चाहते हैं तो इसे सूची में परिवर्तित करें।


3

@LazerBanana द्वारा दिए गए उत्तर के आधार पर, मैं ऑब्जेक्ट की आईडी द्वारा सॉर्ट किए गए सेट का अपना उदाहरण रखूंगा:

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

बस के मामले में आप का उपयोग नहीं करना चाहते हैं TreeSetआप इस कोशिश कर सकते हैं।

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

2

मेरी विनम्र राय में, LazerBanana का उत्तर शीर्ष रेटेड उत्तर होना चाहिए और स्वीकार किया जाना चाहिए क्योंकि सभी अन्य उत्तर java.util.TreeSet(या पहले सूची में कनवर्ट करें फिर Collections.sort(...)परिवर्तित सूची पर कॉल करने के लिए) जो ओपी से पूछने के लिए परेशान नहीं थे कि आपके HashSetपास किस तरह की वस्तुएं हैं। यदि उन तत्वों की पूर्वनिर्धारित प्राकृतिक व्यवस्था है या नहीं और यह वैकल्पिक प्रश्न नहीं है बल्कि एक अनिवार्य प्रश्न है।

यदि आप पहले से ही इंटरफ़ेस को लागू नहीं करते हैं या यदि आप स्पष्ट रूप से कंस्ट्रक्टर में नहीं जा रहे हैं, तो आप अपने HashSetतत्वों को अंदर नहीं ले जा सकते हैं और अपने तत्वों को डालना शुरू नहीं कर सकते हैं । TreeSetComparableComparatorTreeSet

से TreeSetJavaDoc,

एक नया, खाली पेड़ सेट का निर्माण करता है, जो उसके तत्वों के प्राकृतिक क्रम के अनुसार क्रमबद्ध होता है। सेट में सम्मिलित सभी तत्वों को तुलनात्मक इंटरफ़ेस को लागू करना चाहिए। इसके अलावा, ऐसे सभी तत्वों का परस्पर तुलनात्मक होना आवश्यक है: e1.compareTo (e2) को सेट में किसी भी तत्व e1 और e2 के लिए ClassCastException को नहीं फेंकना चाहिए। यदि उपयोगकर्ता सेट में एक तत्व जोड़ने का प्रयास करता है जो इस बाधा का उल्लंघन करता है (उदाहरण के लिए, उपयोगकर्ता एक स्ट्रिंग तत्व को एक सेट में जोड़ने का प्रयास करता है जिसके तत्व पूर्णांक हैं), तो ऐड कॉल एक ClassCastException को फेंक देगा।

यही कारण है कि केवल सभी जावा 8 स्ट्रीम आधारित उत्तर - जहां आप अपने तुलनित्र को मौके पर परिभाषित करते हैं - केवल समझ में आता है क्योंकि POJO में तुलनीय लागू करना वैकल्पिक हो जाता है। प्रोग्रामर को जरूरत पड़ने पर तुलनित्र को परिभाषित करता है। TreeSetइस मूलभूत प्रश्न को पूछे बिना संग्रह करने की कोशिश करना भी गलत है (निंजा का जवाब)। ऑब्जेक्ट प्रकारों को मान लेना Stringया Integerगलत भी है।

कहा कि, अन्य चिंताओं की तरह,

  1. क्रमबद्ध प्रदर्शन
  2. मेमोरी फ़ुट प्रिंट (मूल सेट को बनाए रखना और नए सॉर्ट किए गए सेट बनाना हर बार छँटाई किया जाता है या सेट को - जगह आदि में क्रमबद्ध करना चाहते हैं)

अन्य प्रासंगिक बिंदु भी होने चाहिए। केवल एपीआई की ओर इशारा केवल इरादा नहीं होना चाहिए।

चूँकि ओरिजिनल सेट में पहले से ही केवल अनोखे तत्व होते हैं और डेटा को डुप्लिकेट किए जाने के बाद से सेट किए गए मूल सेट को स्मृति से साफ़ करने की आवश्यकता होती है, इसलिए हल किए गए सेट से भी बाधा बनी रहती है।


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);
    }
  }
 }

input - वेद प्रकाश शर्मा सेब वेद ​​केला

आउटपुट - सेब केले प्रकाश शर्म वेद


1

आप चाहते हैं चाहते हैं अंत Collectionके रूप में होने की Setऔर यदि आप अपने स्वयं निर्धारित करना चाहते हैं natural orderकी तुलना में बल्कि TreeSetतो -

1. Convert HashSetमें List
तरह 2. कस्टम Listका उपयोग कर Comparator
3. Convert वापस Listमें LinkedHashSetव्यवस्था बनाए रखने के
4. प्रदर्शन LinkedHashSet

नमूना कार्यक्रम -

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);
    }
}

आउटपुट -

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

यहाँ संग्रह को क्रमबद्ध किया गया है -

पहला - Stringलंबाई का अवरोही क्रम
दूसरा - Stringवर्णानुक्रमिक पदानुक्रम का अवरोही क्रम


0

आप इसे निम्नलिखित तरीकों से कर सकते हैं:

विधि 1:

  1. एक सूची बनाएं और सभी हैशसेट मूल्यों को इसमें संग्रहीत करें
  2. कलेक्शंस। सॉर्ट () का उपयोग करके सूची को क्रमबद्ध करें
  3. सूची को लिंक्डहैसेट में वापस संग्रहीत करें क्योंकि यह प्रविष्टि क्रम को संरक्षित करता है

विधि 2:

  • ट्रीसेट बनाएं और उसमें सभी वैल्यूज को स्टोर करें।

विधि 2 अधिक बेहतर है क्योंकि अन्य विधि हैशसेट और सूची के बीच डेटा को आगे और पीछे स्थानांतरित करने के लिए बहुत समय लेती है।


0

हम यह तय नहीं कर सकते हैं कि हैशसेट के तत्वों को स्वचालित रूप से हल किया जाएगा। लेकिन हम उन्हें TreeSet या किसी भी सूची जैसे ArrayList या LinkedList आदि में परिवर्तित करके सॉर्ट कर सकते हैं।

// 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

आप उसी के लिए अमरूद पुस्तकालय का उपयोग कर सकते हैं

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

आप इसे ट्रीसेट में इस तरह लपेट सकते हैं:

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);   

आउटपुट:
mySet आइटम [1, 3, 4, 5]
ट्रीसेट आइटम [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);

उत्पादन:
mySet आइटम [छह, चार, पांच, दो, योगिनी]
पेड़ आइटम [योगिनी, पांच, चार, छह, दो]

इस पद्धति के लिए आवश्यकता यह है कि सेट / सूची की वस्तुएं तुलनीय होनी चाहिए (तुलनात्मक इंटरफ़ेस लागू करें)


-4

इस सरल आदेश ने मेरे लिए यह काम किया:

myHashSet.toList.sorted

मैंने इसका उपयोग एक प्रिंट स्टेटमेंट के भीतर किया है, इसलिए यदि आपको वास्तव में ऑर्डर जारी रखने की आवश्यकता है, तो आपको इस धागे पर प्रस्तावित ट्रीसेट्स या अन्य संरचनाओं का उपयोग करने की आवश्यकता हो सकती है।


1
मैं नहीं देखता कि हशसेट या सेट के पास कोई तरीका है toList
थॉमस Eizinger

1
यह मेरे लिए स्काला जैसा दिखता है, जो दुर्भाग्य से जावा में समस्या को हल नहीं करता है।
रॉबर्टो

। विधि, कैसे संभव है?
वेद प्रकाश
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.