जब तुलनीय और तुलनात्मक का उपयोग करें


108

मेरे पास वस्तुओं की एक सूची है जो मुझे एक क्षेत्र पर सॉर्ट करने की आवश्यकता है, स्कोर कहते हैं। बहुत अधिक विचार किए बिना मैंने एक नया वर्ग लिखा जो कि कम्प्लायंट को लागू करता है, जो कार्य करता है और यह काम करता है।

अब इस पर पीछे मुड़कर, मैं सोच रहा हूं कि क्या मेरे पास एक नया वर्ग बनाने के बजाय मेरी कक्षा को तुलनात्मक रूप से लागू करना चाहिए जो कि तुलनाकर्ता को लागू करता है। स्कोर ही एकमात्र ऐसा क्षेत्र है, जिस पर वस्तुओं का ऑर्डर दिया जाएगा।

  1. मैंने अभ्यास के रूप में स्वीकार्य क्या किया है?

  2. क्या सही दृष्टिकोण "पहले वर्ग को तुलनात्मक (प्राकृतिक क्रम के लिए) लागू किया गया है और यदि एक वैकल्पिक क्षेत्र की तुलना की आवश्यकता है, तो एक नया वर्ग बनाएं जो कि तुलना को लागू करता है"?

  3. यदि (2) ऊपर सत्य है, तो क्या इसका मतलब यह है कि किसी व्यक्ति को तुलनात्मक श्रेणी लागू करने के बाद ही तुलनाकर्ता को लागू करना चाहिए? (मैं मूल वर्ग का मालिक हूं)।

जवाबों:


80

मैं कहूंगा कि किसी वस्तु को तुलनात्मक रूप से लागू करना चाहिए यदि वह कक्षा को क्रमबद्ध करने का स्पष्ट प्राकृतिक तरीका है, और किसी को भी कक्षा को क्रमबद्ध करने की आवश्यकता होगी, जो आमतौर पर उस तरह से करना चाहते हैं।

यदि, हालांकि, छंटाई कक्षा का एक असामान्य उपयोग था, या छँटाई केवल एक विशिष्ट उपयोग के मामले के लिए समझ में आता है, तो एक तुलनित्र एक बेहतर विकल्प है।

एक और तरीका रखो, वर्ग नाम दिया गया है, क्या यह स्पष्ट है कि एक तुलनीय कैसे सॉर्ट करेगा, या क्या आपको javadoc पढ़ने का सहारा लेना होगा? यदि यह बाद का है, तो ऑड्स हर भविष्य की छँटाई के उपयोग के मामले में एक तुलनित्र की आवश्यकता होती है, जिस बिंदु पर तुलनीय के कार्यान्वयन से कक्षा के उपयोगकर्ता धीमा हो सकते हैं, न कि उन्हें गति प्रदान करते हैं।


क्या आप कृपया एक त्वरित उदाहरण दे सकते हैं?
1

यह अच्छा उदाहरण हो सकता है: gist.github.com/yclian/2627608 तुलना वर्ग का उपयोग करने वाले संस्करण वर्ग है। संस्करण - कारखाने के तरीकों के साथ प्रदान करता है तुलना करने योग्य वस्तु (कोई स्थिर तरीकों के साथ) माना जाता है - एक ऐसा संस्करण प्रदान करता है जो एक दूसरे से तुलना करने में सक्षम है। जिम्मेदारियां अलग हो जाती हैं।
Ses


इंटरव्यूअर ने पूछा, कंपैरिलेटर का उपयोग क्यों करें जब कम्पेरिबल के साथ भी ऐसा ही किया जा सकता है, और मैं गूंगा था :(
आजम

@aLearner लिंक मृत है
G.Brown

127

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

Comparatorयदि आप बाहरी नियंत्रणीय आदेश व्यवहार को परिभाषित करना चाहते हैं तो इसका उपयोग करें , यह डिफ़ॉल्ट आदेश व्यवहार को ओवरराइड कर सकता है।


3
यह एक तकनीकी व्याख्या है, और जैसा कि वे आते हैं, सही है, लेकिन यह वास्तव में सर्वोत्तम प्रथाओं के बारे में कुछ नहीं कहता है।
extraneon

40
यह बता रहा है कि प्रत्येक का उपयोग कब करना है - यदि वह सबसे अच्छा अभ्यास नहीं है, तो यह क्या है?
Bozho

1
"क्या Comparableइसका मतलब यह है कि मैं प्राकृतिक व्यवस्था को परिभाषित कर रहा हूं?" , इसने मुझे वह उत्तर दिया जिसकी मुझे तलाश थी। धन्यवाद :)
सोमजीत

61

उपयोग करें Comparable:

  • यदि वस्तु आपके नियंत्रण में है।
  • यदि तुलनात्मक व्यवहार मुख्य तुलनात्मक व्यवहार है।

उपयोग करें Comparator:

  • यदि वस्तु आपके नियंत्रण से बाहर है और आप उन्हें लागू नहीं कर सकते Comparable
  • जब आप व्यवहार को डिफ़ॉल्ट (जो कि द्वारा निर्दिष्ट किया गया है Comparable) से भिन्न व्यवहार की तुलना करना चाहते हैं।

20

तुलनीय -java.lang.Comparable: int compareTo(Object o1)

एक तुलनीय वस्तु अन्य वस्तु के साथ तुलना करने में सक्षम है। वर्ग को अपने उदाहरणों की तुलना करने में सक्षम होने के लिए java.lang.Comparable इंटरफ़ेस को लागू करना चाहिए।

  • प्रदान की गई वस्तु के साथ वर्तमान वस्तु की तुलना करने में सक्षम।
  • इसका उपयोग करके हम only one sort sequenceउदाहरणों के गुणों के आधार पर लागू कर सकते हैं। पूर्व:Person.id
  • कुछ पूर्वनिर्धारित कक्षाएं जैसे स्ट्रिंग, रैपर कक्षाएं, दिनांक, कैलेंडर ने तुलनात्मक इंटरफ़ेस लागू किया है।

तुलनित्र -java.util.Comparator: int compare(Object o1, Object o2)

एक तुलनित्र वस्तु दो अलग-अलग वस्तुओं की तुलना करने में सक्षम है। वर्ग अपने उदाहरणों की तुलना नहीं कर रहा है, लेकिन कुछ अन्य वर्ग के उदाहरण हैं। इस तुलनित्र वर्ग को java.util.Comparator इंटरफ़ेस को लागू करना चाहिए।

  • समान प्रकार के किसी भी दो वस्तुओं की तुलना करने में सक्षम।
  • इसका उपयोग करके हम many sort sequenceउदाहरणों के गुणों के आधार पर प्रत्येक को लागू और नाम दे सकते हैं। पूर्व:Person.id, Person.name, Person.age
  • हम अनुकूलित छँटाई के लिए हमारे पूर्व-परिभाषित कक्षाओं के लिए तुलनित्र इंटरफ़ेस को लागू कर सकते हैं।

उदाहरण:

public class Employee implements Comparable<Employee> {

    private int id;
    private String name;
    private int age;
    private long salary;

    // Many sort sequences can be created with different names.
    public static Comparator<Employee> NameComparator = new Comparator<Employee>() {         
        @Override
        public int compare(Employee e1, Employee e2) {
            return e1.getName().compareTo(e2.getName());
        }
    };
    public static Comparator<Employee> idComparator = new Comparator<Employee>() {       
        @Override
        public int compare(Employee e1, Employee e2) {
            return Integer.valueOf(e1.getId()).compareTo(Integer.valueOf(e2.getId()));
        }
    };

    public Employee() { }
    public Employee(int id, String name, int age, long salary){
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
    // setters and getters.

    // Only one sort sequence can be created with in the class.
    @Override
    public int compareTo(Employee e) {
    //return Integer.valueOf(this.id).compareTo(Integer.valueOf(e.id));
    //return Character.toString(this.name.charAt(0)).compareToIgnoreCase(Character.toString(e.name.charAt(0)));
        if (this.id > e.id) {
            return 1;
        }else if(this.id < e.id){
            return -1;
        }else {
            return Character.toString(this.name.charAt(0)).compareToIgnoreCase(Character.toString(e.name.charAt(0)));
        }

    }   

    public static void main(String[] args) {

        Employee e1 = new Employee(5, "Yash", 22, 1000);
        Employee e2 = new Employee(8, "Tharun", 24, 25000);

        List<Employee> list = new ArrayList<Employee>();
        list.add(e1);
        list.add(e2);
        Collections.sort(list); // call @compareTo(o1)
        Collections.sort(list, Employee.nameComparator); // call @compare (o1,o2)
        Collections.sort(list, Employee.idComparator); // call @compare (o1,o2)
    }
}
  • अनुकूलित छँटाई के लिए हम तुलनित्र @compare (o1, o2) के लिए जाते हैं अन्य परिदृश्यों के लिए हम तुलनीय @compareTo (ओ 1) के लिए जाते हैं, बदलते कोड के साथ यदि हम एक से अधिक फ़ील्ड को सॉर्ट करना चाहते हैं तो हम तुलनित्र का उपयोग करते हैं।

के लिए जावा 8 लैम्ब्डा: तुलनाकारी मेरी पोस्ट का संदर्भ लें।


10

जब आप एक ही कक्षा के उदाहरणों की तुलना करते हैं तो तुलनीय का उपयोग किया जाना चाहिए।

विभिन्न वर्गों के उदाहरणों की तुलना करने के लिए तुलनित्र का उपयोग किया जा सकता है।

तुलनीय वर्ग द्वारा कार्यान्वित किया जाता है जिसे अपनी वस्तुओं के लिए प्राकृतिक आदेश को परिभाषित करने की आवश्यकता होती है। जैसे स्ट्रिंग इम्प्लीमेंट्स तुलनात्मक।

यदि कोई एक अलग क्रमबद्ध क्रम चाहता है तो वह तुलनित्र को लागू कर सकता है और दो उदाहरणों की तुलना करने के अपने तरीके को परिभाषित कर सकता है।


10

अगर वस्तुओं की छँटाई प्राकृतिक क्रम पर आधारित होनी चाहिए तो तुलनीय का उपयोग करें जबकि यदि आपकी छँटाई अलग-अलग वस्तुओं के गुणों पर की जानी चाहिए, तो जावा में तुलनात्मक का उपयोग करें।

तुलनीय और तुलनित्र के बीच मुख्य अंतर:

+------------------------------------------------------------------------------------+
¦               Comparable                ¦                Comparator                ¦
¦-----------------------------------------+------------------------------------------¦
¦ java.lang.Comparable                    ¦ java.util.Comparator                     ¦
¦-----------------------------------------+------------------------------------------¦
¦ int objOne.compareTo(objTwo)            ¦ int compare(objOne, objTwo)              ¦
¦-----------------------------------------+------------------------------------------¦
¦ Negative, if objOne < objTwo            ¦ Same as Comparable                       ¦
¦ Zero,  if objOne == objTwo              ¦                                          ¦
¦ Positive,  if objOne > objTwo           ¦                                          ¦
¦-----------------------------------------+------------------------------------------¦
¦ You must modify the class whose         ¦ You build a class separate from to sort. ¦
¦ instances you want to sort.             ¦ the class whose instances you want       ¦
¦-----------------------------------------+------------------------------------------¦
¦ Only one sort sequence can be created   ¦ Many sort sequences can be created       ¦
¦-----------------------------------------+------------------------------------------¦
¦ Implemented frequently in the API by:   ¦ Meant to be implemented to sort          ¦
¦ String, Wrapper classes, Date, Calendar ¦ instances of third-party classes.        ¦
+------------------------------------------------------------------------------------+

9

तुलनित्र वह सब कुछ करता है जो तुलनीय करता है, और अधिक।

| | Comparable | Comparator ._______________________________________________________________________________ Is used to allow Collections.sort to work | yes | yes Can compare multiple fields | yes | yes Lives inside the class you’re comparing and serves | | as a “default” way to compare | yes | yes Can live outside the class you’re comparing | no | yes Can have multiple instances with different method names | no | yes Input arguments can be a list of | just Object| Any type Can use enums | no | yes

मुझे अनाम वर्गों के रूप में तुलना करने वालों का उपयोग करने का सबसे अच्छा तरीका मिला:

private static void sortAccountsByPriority(List<AccountRecord> accounts) {
    Collections.sort(accounts, new Comparator<AccountRecord>() {

        @Override
        public int compare(AccountRecord a1, AccountRecord a2) {
            return a1.getRank().compareTo(a2.getRank());
        }
    });
}

आप जिस वर्ग को क्रमबद्ध करने की योजना बना रहे हैं, उसके अंदर आप इस तरह के कई संस्करण बना सकते हैं। तो आपके पास हो सकता है:

  • sortAccountsByPriority
  • sortAccountsByType
  • sortAccountsByPriorityAndType

    आदि...

अब, आप इन प्रकार के तरीकों का उपयोग कर सकते हैं और कोड का पुन: उपयोग कर सकते हैं। यह मुझे सब कुछ एक तुलनीय देता है, प्लस अधिक ... इसलिए मुझे तुलनीय उपयोग करने का कोई कारण नहीं दिखता है।


8

में कहना चाहूंगा:

  • यदि तुलना सहज है, तो हर तरह से तुलना को लागू करें
  • यदि यह स्पष्ट नहीं है कि आपकी तुलना सहज है, तो तुलनाकर्ता का उपयोग करें क्योंकि यह अधिक स्पष्ट है और इस प्रकार कोड को बनाए रखने के लिए खराब आत्मा के लिए अधिक स्पष्ट है।
  • यदि एक से अधिक सहज ज्ञान युक्त तुलना संभव है तो मैं तुलना करना पसंद करूंगा, संभवतः कक्षा में एक कारखाना विधि द्वारा निर्मित किया जा सकता है।
  • यदि तुलना विशेष उद्देश्य है, तो तुलना का उपयोग करें

6

निम्नलिखित बिंदु आपको यह तय करने में मदद करते हैं कि किन परिस्थितियों में तुलना का उपयोग किया जाना चाहिए और किस तुलना में:

1) कोड लाभ

2) एकल बनाम एकाधिक छँटाई मानदंड

3) Arays.sort () और Collection.sort ()

4) SortedMap और SortedSet में कुंजी के रूप में

5) अधिक संख्या में वर्सस लचीलापन

6) इंटरक्लास तुलना

7) प्राकृतिक आदेश

अधिक विस्तृत लेख के लिए आप उल्लेख कर सकते हैं कि तुलनीय का उपयोग कब करना है और तुलनित्र का उपयोग कब करना है


मुझे आश्चर्य है कि कोई भी इस जवाब को क्यों नहीं बढ़ा रहा है। यह वास्तव में अच्छा है। +1
दिगंत

4
  • यदि कक्षा लिखने के क्षण में आपके पास छँटाई के उपयोग का केवल एक ही उपयोग मामला है तो तुलनात्मक।
  • केवल तभी जब आपके पास छांटने की एक से अधिक रणनीति हो, एक कम्प्लाइटर लागू करें।

4

यदि आपको प्राकृतिक ऑर्डर सॉर्टिंग की आवश्यकता है - उपयोगकर्ता तुलनीय यदि आपको कस्टम ऑर्डर सॉर्टिंग की आवश्यकता है - तुलनित्र का उपयोग करें

उदाहरण:

Class Employee{
private int id;
private String name;
private String department;
}

प्राकृतिक ऑर्डर सॉर्टिंग आईडी पर आधारित होगा क्योंकि यह अद्वितीय होगा और कस्टम ऑर्डर सॉर्टिन जी नाम और विभाग होगा।

Refrences:
एक कक्षा की तुलना और / या तुलनित्र कब होना चाहिए? http://javarevisited.blogspot.com/2011/06/comparator-and-comparable-in-java.html


3

यहाँ भी इसी तरह का प्रश्न था: एक कक्षा को तुलनात्मक और / या तुलनात्मक कब होना चाहिए?

मैं निम्नलिखित कहूंगा: एक प्राकृतिक आदेश की तरह कुछ के लिए तुलनात्मक कार्यान्वयन, उदाहरण के लिए एक आंतरिक आईडी पर आधारित

एक तुलनित्र को लागू करें यदि आपके पास एल्गोरिथ्म की तुलना में अधिक जटिल है, जैसे कई क्षेत्र और इतने पर।


1
कई क्षेत्रों पर ऑर्डर करना उतना ही अच्छा हो सकता है जितना कि इसके साथ Comparable
BalusC

तुलनीय और तुलनित्र के बीच अंतर के लिए आप java-journal.blogspot.in/2010/12/… का
एक शिक्षार्थी

2

तुलनीय:
जब भी हम केवल सजातीय तत्वों और डिफ़ॉल्ट प्राकृतिक सॉर्टिंग ऑर्डर को स्टोर करना चाहते हैं, हम क्लास कार्यान्वयन comparableइंटरफ़ेस के लिए जा सकते हैं ।

तुलनित्र:
जब भी हम सजातीय और विषम तत्वों को संग्रहीत करना चाहते हैं और हम डिफ़ॉल्ट अनुकूलित क्रमबद्ध क्रमबद्ध करना चाहते हैं, हम comparatorइंटरफ़ेस के लिए जा सकते हैं ।


0

मेरी जरूरत तारीख के आधार पर छाँटी गई थी।

इसलिए, मैंने तुलनीय का इस्तेमाल किया और यह मेरे लिए आसानी से काम कर गया।

public int compareTo(GoogleCalendarBean o) {
    // TODO Auto-generated method stub
    return eventdate.compareTo(o.getEventdate());
}

तुलनीय के साथ एक प्रतिबंध यह है कि वे सूची के अलावा अन्य संग्रह के लिए उपयोग नहीं कर सकते हैं।


0

आप वर्ग के मालिक हैं बेहतर के साथ जाने के तुलनीय । आम तौर पर तुलनित्र का उपयोग तब किया जाता है जब आप कक्षा के मालिक नहीं होते हैं, लेकिन आपको इसका उपयोग एक ट्रीसेट या ट्रीपाउप में करना होगा क्योंकि ट्रीज़रेट या ट्रीपैप के कंसट्रक्टर में एक पैरामीटर के रूप में तुलनित्र को पारित किया जा सकता है। आप देख सकते हैं कि कैसे http://precitelyconcise.com/java/collections/g_comparator.php में तुलना और तुलना का उपयोग करें


0

मुझे साक्षात्कार में से एक में nlogn समय की तुलना में बेहतर संख्या में एक निश्चित सीमा की छंटनी करने के लिए कहा गया है। (काउंटिंग सॉर्ट का उपयोग नहीं)

किसी ऑब्जेक्ट पर तुलनात्मक इंटरफ़ेस को लागू करना, सॉर्टिंग तत्वों को ऑर्डर करने के लिए ओवरराइड तुलनात्मक पद्धति का उपयोग करने के लिए निहित छंटनी की अनुमति देता है और यह रैखिक समय होगा।


0

तुलनात्मक है संख्यात्मक मानों के लिए प्रदान किया गया डिफ़ॉल्ट प्राकृतिक सॉर्टिंग क्रम आरोही है और तारों के लिए वर्णमाला क्रम है। उदाहरण के लिए:

Treeset t=new Treeset();
t.add(2);
t.add(1);
System.out.println(t);//[1,2]

तुलनित्र कस्टम myComparator वर्ग में लागू कस्टम छँटाई क्रम है उदाहरण के लिए एक तुलना विधि ओवरराइड करके:

Treeset t=new Treeset(new myComparator());
t.add(55);
t.add(56);
class myComparator implements Comparator{
public int compare(Object o1,Object o2){
//Descending Logic
}
}
System.out.println(t);//[56,55]

-1

बहुत सरल दृष्टिकोण यह मान लेना है कि प्रश्न में इकाई वर्ग को डेटाबेस में दर्शाया जाता है और फिर डेटाबेस तालिका में आपको इकाई वर्ग के क्षेत्रों से बने सूचकांक की आवश्यकता होगी? यदि उत्तर हां है तो तुलनीय लागू करें और प्राकृतिक छँटाई क्रम के लिए सूचकांक क्षेत्र का उपयोग करें। अन्य सभी मामलों में तुलनित्र का उपयोग करें।


-2

लागू करने के लिए मेरा एनोटेशन एफबीआई Comparableऔर Comparator:

public class Person implements Comparable<Person> {         
    private String firstName;  
    private String lastName;         
    private int age;         
    private char gentle;         

    @Override         
    @CompaProperties({ @CompaProperty(property = "lastName"),              
        @CompaProperty(property = "age",  order = Order.DSC) })           
    public int compareTo(Person person) {                 
        return Compamatic.doComparasion(this, person);         
    }  
}

अधिक उदाहरण देखने के लिए लिंक पर क्लिक करें। http://code.google.com/p/compamatic/wiki/CompamaticByExamples

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