5

जावा 8 से पहले, हम Comparable.compareTo(...) इस तरह लागू किया इस:जावा 8 के Comperator.comparing (...) के साथ CompareToBuilder बदलें thenComparing (...)

public int compare(Person a, Person b) { 
    return Comparator 
      .comparing(Person::getLastName) 
      .thenComparing(Person::getFirstName) 
      .compare(a, b); 
} 

नया जावा 8 रास्ता हमें commons-lang3 निर्भरता छोड़ने के लिए अनुमति दे सकते हैं। क्या नया जावा 8 रास्ता तेज है? क्या स्वचालित रूप से माइग्रेट करने का कोई तरीका है? मुझे इसके लिए इंटेलिजे इरादा नहीं मिला।


सूचना जब वहाँ रिवर्स आदेश और गैर प्राकृतिक तुलना कर रहे हैं शामिल है कि यह थोड़ा और अधिक जटिल हो जाता है:

public int compare(SingleBenchmarkResult a, SingleBenchmarkResult b) { 
    return new CompareToBuilder() 
      .append(b.hasAnyFailure(), a.hasAnyFailure()) // Reverse 
      .append(a.getAverageScore(), b.getAverageScore(), resilientScoreComparator) 
      .toComparison(); 
} 

हो जाता है

public int compare(SingleBenchmarkResult a, SingleBenchmarkResult b) { 
    return Comparator 
      .comparing(SingleBenchmarkResult::hasAnyFailure, Comparator.reverseOrder()) // Reverse 
      .thenComparing(SingleBenchmarkResult::getAverageScore, resilientScoreComparator) 
      .compare(a, b); 
} 

उत्तर

2

मुझे नहीं लगता कि किसी भी करते हैं इसके लिए पूर्व परिभाषित निरीक्षण। आप IntelliJ के structural-search का उपयोग करने का प्रयास कर सकते हैं, हालांकि मुझे लगता है कि हर संभव मामले के लिए ऐसा करना मुश्किल हो सकता है। (2 $TYPE$ और $z$ की घटना गिनती है)

खोज टेम्पलेट: दो तुलना के साथ एक सरल मामले के लिए एक संभावना यह निम्न हो सकता है

$ReturnType$ $MethodName$($TYPE$ $z$) { 
     return new CompareToBuilder() 
       .append($A$.$m$(), $B$.$m$()) 
       .append($A$.$m1$(), $B$.$m1$()) 
       .toComparison(); 
    } 

प्रतिस्थापन टेम्पलेट:

$ReturnType$ $MethodName$($TYPE$ $z$) { 
    return java.util.Comparator 
      .comparing($TYPE$::$m$) 
      .thenComparing($TYPE$::$m1$) 
      .compare($A$, $B$); 
} 

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

6

आप इसे इस तरह

public int compare(Person a, Person b) { 
    return Comparator 
      .comparing(Person::getLastName) 
      .thenComparing(Person::getFirstName) 
      .compare(a, b); 
} 

आप प्रत्येक तुलना के लिए एक नया Comparator का निर्माण करके प्रदर्शन बर्बाद कर रहे लिखते हैं। और आसपास के कोड को देखते समय यह स्पष्ट रूप से बकवास होना चाहिए। compare(Person a, Person b) विधि निश्चित रूप से Comparator<Person> लागू करने वाली कक्षा का हिस्सा है, जिसे आप वांछित तुलनित्र प्राप्त करने के लिए किसी स्थान पर तत्काल स्थानांतरित करते हैं। आपको को उदाहरण को एकमात्र Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName) उदाहरण के बजाय प्रतिस्थापित करना चाहिए, पूरे ऑपरेशन में उपयोग किया जाता है।

उदा।

// reusable 
static final Comparator<Person> By_NAME = Comparator 
      .comparing(Person::getLastName).thenComparing(Person::getFirstName); 

या तदर्थ

listOfPersons.sort(Comparator.comparing(Person::getLastName) 
          .thenComparing(Person::getFirstName)); 

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

+0

मुझे व्यक्ति की प्राकृतिक तुलना को लागू करने की आवश्यकता है, इसलिए मैं इन सुझाए गए परिवर्तनों को लागू नहीं कर सकता। क्या आपको लगता है कि Comparator.comparing (...) तुलनात्मक बिल्डर से भी धीमी है? –

+1

यदि आप प्राकृतिक आदेश को लागू करते हैं, तो विधि 'तुलना (व्यक्ति, व्यक्ति)' की तुलना में 'तुलना (व्यक्ति)' की तुलना में की जानी चाहिए, इसलिए सवाल भ्रामक था। मुझे नहीं लगता कि 'Comparator.comparing' का उपयोग' तुलनात्मक बिल्डर 'से धीमा हो जाएगा, लेकिन फिर भी, आप मेरे उत्तर में दिखाए गए 'स्थिर अंतिम' फ़ील्ड को घोषित करके इसे सुधार सकते हैं और' तुलना करने के लिए (व्यक्ति) '' BY_NAME.compare (यह, अन्य) वापस करें; '। – Holger

+0

अच्छा बिंदु। असल में मैंने उन मामलों का उपयोग किया है जहां यह प्राकृतिक आदेश है और मैंने उन मामलों का उपयोग किया है जहां यह एक पुन: प्रयोज्य कॉम्परेटर (ऊपर की तरह) है। मैं देखता हूं कि उस विशेष कॉम्परेटर को एक अलग वर्ग बनाने के लिए अब इसकी आवश्यकता क्यों नहीं है। –

संबंधित मुद्दे