जावा में सॉर्ट किया गया संग्रह


161

मैं जावा में एक शुरुआत कर रहा हूँ। कृपया सुझाव दें कि जावा में क्रमबद्ध सूची को बनाए रखने के लिए कौन सा संग्रह (ओं) का उपयोग किया जा सकता है। मैंने कोशिश की है Mapऔर Set, लेकिन वे नहीं थे जो मैं देख रहा था।

जवाबों:


187

यह बहुत देर से आता है, लेकिन JDK में एक वर्ग है जो केवल क्रमबद्ध सूची होने के उद्देश्य से है। यह नाम दिया गया है (अन्य Sorted*इंटरफेस के साथ कुछ हद तक बाहर ) " java.util.PriorityQueue"। यह Comparable<?>या तो s या a का उपयोग करके सॉर्ट कर सकता है Comparator

एक Listसॉर्ट किए गए उपयोग के साथ अंतर Collections.sort(...)यह है कि यह ओ (लॉग (एन)) सम्मिलन प्रदर्शन के साथ, एक ढेर डेटा संरचना का उपयोग करके, हर समय एक आंशिक क्रम बनाए रखेगा, जबकि एक सॉर्ट में डालने से ArrayListओ (एन) होगा (यानी, बाइनरी खोज और चाल का उपयोग करते हुए)।

हालांकि, एक के विपरीत List, PriorityQueueअनुक्रमित पहुंच ( get(5)) का समर्थन नहीं करता है , एक ढेर में आइटम तक पहुंचने का एकमात्र तरीका उन्हें बाहर निकालना है, एक समय में (इस प्रकार नाम PriorityQueue)।


4
imo यह उत्तर अधिक उत्तोलन का हकदार है क्योंकि यह एकमात्र संग्रह को इंगित करता है जो JDK में क्षमता
रखता है

96
जावेदोक से: "मेथेटर इटरेटर () में प्रदान किया गया इटरेटर किसी विशेष क्रम में प्रायरिटी क्यू के तत्वों को पार करने की गारंटी नहीं है।"
क्रिस्चोफ़र हैमरस्ट्रॉम्

10
@ जिराफ: एक प्राथमिकता कतार सिर्फ इतनी है, एक डेटा संरचना जो एक प्राथमिकता कतार रखने में बहुत कुशल है। आप सामने से चुनाव कर सकते हैं और क्रमबद्ध क्रम में डेटा आइटम प्राप्त कर सकते हैं। हालांकि ढेर आंतरिक रूप से तत्वों के कुल क्रम को बनाए नहीं रखते हैं (इसीलिए वे इतने कुशल होते हैं), इसलिए पोल ऑपरेशन को निष्पादित किए बिना तत्वों तक पहुंचने का कोई तरीका नहीं है।
मार्टिन प्रोब्स्ट जूल

2
@ क्रिस्पी यह इस बात पर निर्भर करता है कि आप वास्तव में अपने डेटा स्ट्रक्चर के साथ क्या करना चाहते हैं। हीप्स आइटमों की एक सूची को बनाए रखने और बाद में एक ऑर्डर किए गए फैशन में उन्हें पुनः प्राप्त करने के लिए एक कुशल तरीका है - इट्रेटर का उपयोग करने से काम नहीं होता है, लेकिन यदि आप इससे मतदान करते हैं, तो आप अपने डेटा को क्रम में प्राप्त करेंगे। पुनर्प्राप्ति विनाशकारी है, लेकिन यह अभी भी कई मामलों में ठीक हो सकता है। इसलिए मुझे लगता है कि यह उत्तर अच्छा है।
मार्टिन प्रोब्स्ट

4
@MartinProbst कृपया अपने उत्तर को स्पष्ट रूप से इंगित करें कि वह संग्रह अपेक्षित क्रम में प्राप्त नहीं किया जा सकता है। जैसा कि कई लोगों ने कहा है, यह चरम पर भ्रामक है!
जॉर्ज गैलोवो

53

ट्री मैप और ट्रीसेट आपको क्रमबद्ध क्रम में सामग्री पर एक पुनरावृत्ति देगा। या आप एक ArrayList का उपयोग कर सकते हैं और इसे सॉर्ट करने के लिए Collections.sort () का उपयोग कर सकते हैं। वे सभी वर्ग java.util में हैं


27
हालांकि इसमें दो बड़ी कमियां हैं, पहला यह कि एक सेट में डुप्लिकेट नहीं हो सकते। दूसरा यह है कि यदि आप किसी सूची और संग्रह। () का उपयोग करते हैं, तो आप लगातार विशाल सूचियों को छांटते हैं और खराब प्रदर्शन देते हैं। सुनिश्चित करें कि आप 'गंदे' झंडे का उपयोग कर सकते हैं, लेकिन यह बिल्कुल समान नहीं है।
21

यह एक प्रश्न लाता है कि क्या हमारे पास जावा में एक विकल्प है जो डुप्लिकेट को अनुमति देता है और सेट (संतुलित बाइनरी ट्री) के समान प्रदर्शन भी देता है
mankadnandan

32

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


11
n आवेषण O (n ^ 2) होगा। एक ट्रीसेट आपको क्लीनर कोड और ओ (एन लॉग एन) देगा। OTOH, के लिए एक सरणी के बेतरतीब संशोधन द्विआधारी खोज तेजी से होगा और कम मेमोरी (इसलिए कम जीसी ओवरहेड) का उपयोग करेगा।
टॉम हॉल्टिन -

कोड को साफ रखने के लिए और फिर भी डुप्लिकेट के लिए अनुमति देना एक सॉर्टेडलिस्ट वर्ग बनाने के लिए काफी आसान होगा जो सॉर्ट किए गए क्रम में मूल्यों को सम्मिलित करता है।
श्री शाइनी और न्यू 安 Sh

यदि आप @ टॉमहॉटिन-टैकललाइन द्वारा उल्लिखित कैवेट के साथ रह सकते हैं, तो यह एक सबसे बेहतर उत्तर है, इमो के मुकाबले बेहतर उत्तर। अधिकांश मामलों के लिए यह उम्मीद के मुताबिक काम करने वाला महत्वपूर्ण है।
12

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

शुक्रिया नील, वह भयानक था खूनी!
vikingsteve

31

Google अमरूद के ट्रीमूल्टसेट वर्ग का उपयोग करें । अमरूद का शानदार कलेक्शन एपीआई है।

क्रमबद्ध क्रम बनाए रखने वाली सूची के कार्यान्वयन को प्रदान करने में एक समस्या add()विधि के JavaDocs में किया गया वादा है ।


मल्टीसेट सुझाव के लिए यश
darthtrevino

5
आवश्यकता के उल्लेख के लिए +1 Listजो अंत में हमेशा जोड़ता है।
रोलैंड इलिग

2
ध्यान दें कि TreeMultiSet अभी भी डुप्लिकेट तत्वों (एलिमेंट्स की तुलना नहीं करता है) (0 लौटाता है, न कि बराबर () चेक)। यदि आप एक ही प्राथमिकता के एक से अधिक आइटम जोड़ना चाहते हैं, तो यह केवल पहले जोड़े की संख्या में वृद्धि करेगा, अन्य को छोड़ देगा और प्रभावी रूप से एक अच्छा काउंटिंग बैग कार्यान्वयन होगा।
bekce


12

कुछ विकल्प हैं। यदि आप डुप्लिकेट नहीं चाहते हैं और आप जिन वस्तुओं को सम्मिलित कर रहे हैं, वे ट्रीसेट का सुझाव देंगे।

आप ऐसा करने के लिए संग्रह वर्ग के स्थिर तरीकों का भी उपयोग कर सकते हैं।

अधिक जानकारी के लिए संग्रह # सॉर्ट (java.util.List) और ट्रीसेट देखें ।


10

यदि आप केवल एक सूची को क्रमबद्ध करना चाहते हैं, तो किसी भी प्रकार की सूची का उपयोग करें और संग्रह । एस () का उपयोग करें । यदि आप सुनिश्चित करना चाहते हैं कि सूची में तत्व अद्वितीय हैं और हमेशा क्रमबद्ध हैं, तो SortedSet का उपयोग करें ।


5

मैंने जो भी किया है वह सभी विधियों के साथ आंतरिक उदाहरण वाली सूची को लागू करना है।

 public class ContactList implements List<Contact>, Serializable {
    private static final long serialVersionUID = -1862666454644475565L;
    private final List<Contact> list;

public ContactList() {
    super();
    this.list = new ArrayList<Contact>();
}

public ContactList(List<Contact> list) {
    super();
    //copy and order list
    List<Contact>aux= new ArrayList(list);
    Collections.sort(aux);

    this.list = aux;
}

public void clear() {
    list.clear();
}

public boolean contains(Object object) {
    return list.contains(object);
}

के बाद, मैंने एक नया तरीका "putOrdered" लागू किया है जो उचित स्थिति में सम्मिलित होता है यदि तत्व मौजूद नहीं है या बस मौजूद है।

public void putOrdered(Contact contact) {
    int index=Collections.binarySearch(this.list,contact);
    if(index<0){
        index= -(index+1);
        list.add(index, contact);
    }else{
        list.set(index, contact);
    }
}

यदि आप बार-बार तत्वों को अनुमति देना चाहते हैं, तो इसके बजाय AddOrdered को लागू करें (या दोनों)।

public void addOrdered(Contact contact) {
    int index=Collections.binarySearch(this.list,contact);
    if(index<0){
        index= -(index+1);
    }
    list.add(index, contact);
}

यदि आप आवेषण से बचना चाहते हैं तो आप "ऐड" और "सेट" विधियों पर ऑपरेशन के अपवाद को भी फेंक सकते हैं और असमर्थित कर सकते हैं।

public boolean add(Contact object) {
    throw new UnsupportedOperationException("Use putOrdered instead");
}

... और इसके अलावा आपको लिस्टआईटर के तरीकों से सावधान रहना होगा क्योंकि वे आपकी आंतरिक सूची को संशोधित कर सकते हैं। इस मामले में आप आंतरिक सूची की एक प्रति वापस कर सकते हैं या फिर एक अपवाद फेंक सकते हैं।

public ListIterator<Contact> listIterator() {
    return (new ArrayList<Contact>(list)).listIterator();
}

समस्या यह है कि यह Listअनुबंध का उल्लंघन करता है । शायद केवल लागू करना बेहतर होगा Collection। और अगर ContactListछांटा गया है, तो अधिक कुशल होने के लिए contains()उपयोग binarySearchकिया जा सकता है।
Marcono1234

5

आप जैसे चाहते हैं एक क्रमबद्ध सूची को लागू करने का सबसे कुशल तरीका यहाँ पर एक अनुक्रमिक स्किलिस्ट को लागू करना होगा: इंडेक्सेबल स्किलिस्ट । यह ओ (लॉग (एन)) में आवेषण / हटाने की अनुमति देगा और एक ही समय में अनुक्रमित पहुंच की अनुमति देगा। और यह डुप्लिकेट को भी अनुमति देगा।

Skiplist एक बहुत ही दिलचस्प है और, मैं कहूंगा, डेटा संरचना को कम करके। दुर्भाग्य से जावा बेस लाइब्रेरी में कोई अनुक्रमित स्किलिस्ट कार्यान्वयन नहीं है, लेकिन आप एक ओपन सोर्स कार्यान्वयन का उपयोग कर सकते हैं या इसे स्वयं लागू कर सकते हैं। समसामयिक Skipist कार्यान्वयन जैसे समवर्ती SkipListSet और ConcurrentSkipListMap हैं


4

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


4

लैम्बडाज का उपयोग करना

आप इन कार्यों को लेम्बडाज के साथ हल करने की कोशिश कर सकते हैं यदि आप जावा 8 से पहले के संस्करणों का उपयोग कर रहे हैं। आप इसे यहाँ पा सकते हैं: http://code.google.com/p/lambdaj/

यहाँ आपके पास एक उदाहरण है:

क्रमबद्ध Iterative

List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
        public int compare(Person p1, Person p2) {
           return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
        }
}); 

लैंबडैज के साथ क्रमबद्ध करें

List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

बेशक, प्रदर्शन में इस तरह का सौंदर्य प्रभाव पड़ता है (औसतन 2 बार), लेकिन क्या आप अधिक पठनीय कोड पा सकते हैं?

Lambda अभिव्यक्ति का उपयोग कर जावा 8 के साथ क्रमबद्ध करें

Collections.sort(persons, (p1, p2) -> p1.getAge().compareTo(p2.getAge()));
//or
persons.sort((p1, p2) -> p1.getAge().compareTo(p2.getAge()));

जावा 8 लैम्ब्डा एक्सप्रेशन के साथ अपने अंतिम उदाहरण में, कोई कैसे रिवर्स रिवर्स कर सकता है?
रजत शाह

1
@RajatShah मुझे लगता है कि आप बस कर सकते हैं-(p1.getAge().compareTo(p2.getAge()))
फेडरिको पियाज़ा

@RajatShah ने मदद की खुशी
फेडरिको पियाजा

2

प्रायोरिटी क्यू के साथ समस्या यह है कि यह एक साधारण सरणी द्वारा समर्थित है, और तर्क जो तत्वों को प्राप्त करता है, वह "कतार [2 * n + 1] और कतार [2 * (n + 1)]" चीज़ से होता है। यह बहुत अच्छा काम करता है यदि आप सिर्फ सिर से खींचते हैं, लेकिन इसे बेकार कर देता है यदि आप किसी बिंदु पर इसे .toArray को कॉल करने का प्रयास कर रहे हैं।

मैं com.google.common.collect.TreeMultimap का उपयोग करके इस समस्या के आसपास जाता हूं, लेकिन मैं एक ऑर्डर में लिपटे हुए मानों के लिए एक कस्टम कम्पैरिज़र की आपूर्ति करता हूं, जो कभी 0 नहीं देता है।

पूर्व। डबल के लिए:

private static final Ordering<Double> NoEqualOrder = Ordering.from(new Comparator<Double>() {

    @Override
    public int compare(Double d1, Double d2)
    {
        if (d1 < d2) {
            return -1;
        }
        else {
            return 1;
        }
    }
});

इस तरह से जब मैं .toArray () कॉल करता हूं, तो मुझे मूल्य मिलते हैं, और डुप्लिकेट भी होते हैं।


1

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

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


1

आप Arraylist और Treemap का उपयोग कर सकते हैं, जैसा कि आपने कहा था कि आप बार-बार मान चाहते हैं और फिर आप TreeSet का उपयोग नहीं कर सकते, हालांकि इसे भी क्रमबद्ध किया गया है, लेकिन आपको तुलनित्र को परिभाषित करना होगा।


1

सेट के लिए आप ट्रीसेट का उपयोग कर सकते हैं। ट्रीसेट आदेश एक प्राकृतिक आदेश या उस विशेष वस्तु के लिए तुलनीय के लिए पारित किसी भी छंटनी आदेश के आधार पर तत्व है। मानचित्र के लिए TreeMap का उपयोग करें। ट्रीपाइप कुंजी पर छँटाई प्रदान करता है। ट्रीपॉइंट की कुंजी के रूप में एक ऑब्जेक्ट जोड़ने के लिए उस वर्ग को तुलनीय इंटरफ़ेस को लागू करना चाहिए जो बदले में () विधि की तुलना करने के लिए लागू करता है जिसमें सॉर्टिंग ऑर्डर की परिभाषा होती है। http://techmastertutorial.in/java-collection-impl.html


0

नीचे दी गई सूची को क्रमबद्ध करने के लिए सॉर्ट () विधि का उपयोग करें:

List list = new ArrayList();

//add elements to the list

Comparator comparator = new SomeComparator();

Collections.sort(list, comparator);

संदर्भ के लिए लिंक देखें: http://tutorials.jenkov.com/java-collections/sorting.html


0

उपयोग करें TreeSetजो तत्वों को क्रमबद्ध क्रम में देता है। या Collection.sort()बाहरी छँटाई के लिए उपयोग करें Comparator()


ट्रीसेट तत्वों के दोहराव की अनुमति नहीं देता है। कभी-कभी यह एक वांछित विशेषता है, अन्य नहीं। को ध्यान में रखते ओपी सेट करने की कोशिश की, मैं नहीं के लिए लगता है
usr स्थानीय-ΕΨΗΕΛΩΝ

मत बनो, TreeMap को भी इंगित करें: docs.oracle.com/javase/10/docs/api/java/util/TreeMap.html
Haakon Løtveit

0
import java.util.TreeSet;

public class Ass3 {
    TreeSet<String>str=new TreeSet<String>();
    str.add("dog");
    str.add("doonkey");
    str.add("rat");
    str.add("rabbit");
    str.add("elephant");
    System.out.println(str);    
}

0

Java 8 तुलनित्र के साथ, यदि हम सूची को क्रमबद्ध करना चाहते हैं, तो यहां दुनिया के 10 सबसे अधिक आबादी वाले शहर हैं और हम इसे समय के अनुसार रिपोर्ट करना चाहते हैं। ओसाका, जापान। ... मेक्सिको सिटी मेक्सिको। ... बीजिंग, चीन। ... साओ पाउलो ब्राज़ील। ... मुंबई, भारत। ... शंघाई, चीन। ... दिल्ली, भारत। ... टोक्यो, जापान।

 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;

public class SortCityList {

    /*
     * Here are the 10 most populated cities in the world and we want to sort it by
     * name, as reported by Time. Osaka, Japan. ... Mexico City, Mexico. ...
     * Beijing, China. ... São Paulo, Brazil. ... Mumbai, India. ... Shanghai,
     * China. ... Delhi, India. ... Tokyo, Japan.
     */
    public static void main(String[] args) {
        List<String> cities = Arrays.asList("Osaka", "Mexico City", "São Paulo", "Mumbai", "Shanghai", "Delhi",
                "Tokyo");
        System.out.println("Before Sorting List is:-");
        System.out.println(cities);
        System.out.println("--------------------------------");

        System.out.println("After Use of List sort(String.CASE_INSENSITIVE_ORDER) & Sorting List is:-");
        cities.sort(String.CASE_INSENSITIVE_ORDER);
        System.out.println(cities);
        System.out.println("--------------------------------");
        System.out.println("After Use of List sort(Comparator.naturalOrder()) & Sorting List is:-");
        cities.sort(Comparator.naturalOrder());
        System.out.println(cities);

    }

}

0

उपयोगकर्ता परिभाषित मापदंड के अनुसार एक ArrayList छँटाई।

मॉडल वर्ग

 class Student 
 { 
     int rollno; 
     String name, address; 

     public Student(int rollno, String name, String address) 
     { 
         this.rollno = rollno; 
         this.name = name; 
         this.address = address; 
     }   

     public String toString() 
     { 
         return this.rollno + " " + this.name + " " + this.address; 
     } 
 } 

छँटाई कक्षा

 class Sortbyroll implements Comparator<Student> 
 {         
     public int compare(Student a, Student b) 
     { 
         return a.rollno - b.rollno; 
     } 
 } 

मुख्य वर्ग

 class Main 
 { 
     public static void main (String[] args) 
     { 
         ArrayList<Student> ar = new ArrayList<Student>(); 
         ar.add(new Student(111, "bbbb", "london")); 
         ar.add(new Student(131, "aaaa", "nyc")); 
         ar.add(new Student(121, "cccc", "jaipur")); 

         System.out.println("Unsorted"); 
         for (int i=0; i<ar.size(); i++) 
             System.out.println(ar.get(i)); 

         Collections.sort(ar, new Sortbyroll()); 

         System.out.println("\nSorted by rollno"); 
         for (int i=0; i<ar.size(); i++) 
             System.out.println(ar.get(i)); 
     } 
 } 

उत्पादन

 Unsorted
 111 bbbb london
 131 aaaa nyc
 121 cccc jaipur

 Sorted by rollno
 111 bbbb london
 121 cccc jaipur
 131 aaaa nyc
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.