जावा इंटेगर तुलना () - तुलना बनाम घटाव का उपयोग क्यों करें?


80

मैंने पाया है कि विधि का java.lang.Integerकार्यान्वयन compareToइस प्रकार है:

public int compareTo(Integer anotherInteger) {
    int thisVal = this.value;
    int anotherVal = anotherInteger.value;
    return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}

सवाल यह है कि घटाव के बजाय तुलना का उपयोग क्यों करें:

return thisVal - anotherVal;

27
जब हमें माइक्रो-ऑप्टिमाइज़ेशन के बारे में चिंता करने की इतनी जल्दी होती है, तो हम अक्सर छोटी गाड़ी कोड खत्म कर देते हैं।
केविन बोर्रिलियन

JDK 7 के रूप में, व्यक्ति Integer.compare(thisVal, anotherVal)टर्नरी अभिव्यक्ति को लिखने के बजाय उपयोग कर सकता है ।
स्टुअर्ट मार्क्स

जवाबों:


96

यह पूर्णांक अतिप्रवाह के कारण है। जब thisValबहुत बड़ा होता है और anotherValऋणात्मक होता है, तो बाद वाली को पूर्व की पैदावार से घटा देता है, thisValजो कि उस से बड़ा होता है, जो नकारात्मक सीमा तक बह सकता है।


हाँ, जिस तरह से उन्होंने यहाँ किया है वह शायद अतिप्रवाह एट अल
रोगरडैक के

अमरूद तुलनात्मक का प्रयोग करें। यह बहुत आसान है! google.github.io/guava/releases/22.0/api/docs/com/google/common/…
Andrea Bergonzo

thisValबड़े होने की जरूरत नहीं है। thisValशून्य हो सकता है और anotherValहो सकता है Integer.MIN_VALUEऔर आपके पास पहले से ही एक अतिप्रवाह हो। और मन यह है कि निश्चित रूप से, यह दूसरा रास्ता हो सकता है, thisValueबहुत छोटा और anotherValबल्कि बड़ा, एक दूरी है जो intमूल्य सीमा से अधिक है।
होल्गर

65

दो संख्यात्मक मूल्य की तुलना करने के लिए घटाव "चाल" टूट गया है !!!

        int a = -2000000000;
        int b =  2000000000;
        System.out.println(a - b);
        // prints "294967296"

यहाँ, a < bअभी तक a - bसकारात्मक है।

इस मुहावरे का प्रयोग न करें। यह काम नहीं करता है।

इसके अलावा, यहां तक ​​कि अगर यह काम करता है , यह प्रदर्शन में कोई महत्वपूर्ण सुधार प्रदान नहीं करेगा, और वास्तव में लागत पठनीयता हो सकती है।

यह सभी देखें

  • जावा गूढ़ व्यक्ति पहेली 65: एक अजीब तरह की अजीब गाथा

    इस पहेली के कई पाठ हैं। सबसे विशिष्ट है: एक घटाव-आधारित तुलनित्र का उपयोग न करें जब तक कि आप सुनिश्चित न हों कि मूल्यों के बीच का अंतर कभी भी अधिक नहीं होगा Integer.MAX_VALUE । अधिक आम तौर पर, intअतिप्रवाह से सावधान रहें । एक और सबक यह है कि आपको "चतुर" कोड से बचना चाहिए। स्पष्ट, सही कोड लिखने के लिए प्रयास करें, और इसे तब तक अनुकूलित न करें जब तक कि यह आवश्यक साबित न हो।


2
यह वास्तव में बिल्कुल भी नहीं टूटा है। यदि आप उन संख्याओं के बारे में कुछ भी जानते हैं जो आप तुलना कर रहे हैं, तो आप शायद जानेंगे कि वे तुलना करना सुरक्षित हैं। जानते हुए भी नहीं, बस ((long)a - b)काम करना चाहिए। हालाँकि आप सही कह रहे हैं; यह बहुत कम ही उपयोगी है।
अमरा

4
@naiad सिर्फ ((long)a - b)मदद नहीं करता है, क्योंकि आपको परिणाम को वापस लाना है int, क्योंकि यह है कि तुलनित्र को वापस लौटना है, एक अतिप्रवाह के साथ फिर से समाप्त करना। आपको Long.signumपरिणाम पर कुछ ऐसा करना होगा , जिसे भूलना आसान हो, जैसा कि आपकी टिप्पणी से पता चलता है। और यह उससे अधिक कुशल भी नहीं हो सकता है Integer.compare, जिसे JVM आंतरिक रूप से संभाल सकता है ...
Holger

9

सीधे शब्दों में कहें, तो intदो मध्यस्थ intमूल्यों के बीच अंतर को संग्रहीत करने के लिए प्रकार बड़ा नहीं है । उदाहरण के लिए, 1.5 बिलियन और -1.5 बिलियन के बीच का अंतर 3.0 बिलियन है, लेकिन int2.1 बिलियन से अधिक मूल्य नहीं रख सकते।



1

अतिप्रवाह चीज़ के अलावा, आपको ध्यान देना चाहिए कि विकल्प के साथ संस्करण समान परिणाम नहीं देता है

  • पहला तुलनात्मक संस्करण तीन संभावित मानों में से एक लौटाता है: -1, 0, या 1।
  • यदि आप अंतिम पंक्ति को प्रतिस्थापन के साथ बदलते हैं, तो परिणाम किसी भी पूर्णांक मान हो सकता है।

यदि आप जानते हैं कि कोई अतिप्रवाह नहीं होगा, तो आप कुछ इस तरह का उपयोग कर सकते हैं:

public int compareTo(Integer anotherInteger) {
    return sign(this.value - anotherInteger.valuel);
}

12
आप सही हैं कि परिणाम समान नहीं हैं। लेकिन उन्हें होना आवश्यक नहीं है! compareToकेवल एक नकारात्मक मान, शून्य या एक सकारात्मक मान वापस करने के लिए आवश्यक है, thisअन्य वस्तु के क्रम के आधार पर । Java.sun.com/j2se/1.5.0/docs/api/java/lang/…
क्रिश्चियन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.