जावा में दो वस्तुओं की तुलना संभव शून्य मान से करें


189

मैं जावा में समानता के लिए दो तारों की तुलना करना चाहता हूं, जब या तो या दोनों हो सकते हैं null, इसलिए मैं बस कॉल नहीं कर सकता .equals()। सबसे अच्छा तरीका क्या है?

boolean compare(String str1, String str2) {
    ...
}

संपादित करें:

return ((str1 == str2) || (str1 != null && str1.equals(str2)));

जवाबों:


173

यह वह है जो जावा आंतरिक कोड का उपयोग करता है (अन्य compareतरीकों पर):

public static boolean compare(String str1, String str2) {
    return (str1 == null ? str2 == null : str1.equals(str2));
}

3
केवल स्ट्रिंग प्रकारों को वस्तुओं में क्यों नहीं बदला जाए - इसे और अधिक सामान्य बना दिया जाए? और फिर यह अगर आप जावा 7. करने के लिए ले जाने के क्या मिलेगा रूप में ही है
टॉम

3
आपको किस जावा वर्ग में विधि प्रदान की गई है?
वलोडिमिर लेविक्टस्की 13

30
अरे! आपके पास सही / गलत लौटने वाली तुलना विधि नहीं होनी चाहिए। बराबरी की तुलना के समान नहीं है। तुलना छँटाई के लिए उपयोगी होनी चाहिए। आपको वापस लौटना चाहिए <0, ==0या >0यह इंगित करने के लिए कि कौन सा दूसरे से कम है / ग्रेटर है
कोया

10
मैं सुझाव देता हूं कि Objects.equals(Object, Object)मार्क रोटेटेवेल ने अपने उत्तर में बताया है (कृपया इसे आगे बढ़ाएं)
नीरन

1
@ यह वास्तव में एक अच्छा जवाब से कम नहीं करता है। मुझे यकीन है कि आप सबसे अच्छा जवाब नहीं देंगे बहस हमेशा एक ही कोड युक्त होता है जो हर जावा संस्करण के साथ संगत होता है जो हमेशा मौजूद रहता है
Neuron

315

जावा 7 के बाद से आप java.util.Objects.equals(Object, Object)दो वस्तुओं पर समान जांच करने के लिए उनके बारे में परवाह किए बिना स्थिर विधि का उपयोग कर सकते हैं null

दोनों वस्तुओं रहे हैं nullयह वापस आ जाएगी true, अगर एक है nullऔर एक अन्य यह वापस आ जाएगी नहीं है false। अन्यथा यह equalsतर्क के रूप में दूसरे के साथ पहली वस्तु पर कॉल करने का परिणाम लौटाएगा ।


यह दृष्टिकोण प्रोग्राम के रनटाइम तक प्रकार की जांच को रोकता है। दो परिणाम: यह रनटाइम पर धीमा हो जाएगा और आईडीई आपको यह नहीं बताएगा कि क्या आप गलती से विभिन्न प्रकारों की तुलना करने का प्रयास करते हैं।
1

10
@averasko जब आप उपयोग करते हैं Object.equals(Object)तो कोई संकलन समय जाँच नहीं है। Objects.equals(Object, Object)बहुत ज्यादा एक सामान्य रूप में एक ही काम करता है equals, और फिर निष्कर्ष / आईडीई द्वारा चेक, उन नियमों वह भी के लिए समर्थन कर रहे heuristics हैं Objects.equals(Object, Object)(उदाहरण के लिए IntelliJ विचार 2016.2 दोनों सामान्य बराबरी और वस्तुओं से एक के लिए एक ही जांच है)।
मार्क रोटिटेवेल

2
मुझे यह तरीका पसंद है। इन दिनों चीजों के लिए कुछ ApacheCommons लाइब्रेरी को शामिल करने की आवश्यकता नहीं है।
टॉर्स्टन ओजापर्व 12

1
@SimonBaars यह एक अशक्त वस्तु पर कार्य नहीं कर रहा है, यह एक स्थिर विधि है जिसे आप दो तर्क पास करते हैं, जो अशक्त हो सकता है, या किसी वस्तु का संदर्भ हो सकता है।
मार्क रोटेवेल

8
imho यह स्वीकृत उत्तर होना चाहिए। मैं अपने हर एक आवेदन में पहिया को फिर से मजबूत नहीं करना चाहता हूं जो मैं लिखता हूं
न्यूरॉन

45

इन मामलों के लिए Apache Commons StringUtils # बराबर का उपयोग करना बेहतर होगा , यह पहले से ही अशक्त तारों को संभालता है। कोड नमूना:

public boolean compare(String s1, String s2) {
    return StringUtils.equals(s1, s2);
}

यदि आप लाइब्रेरी को जोड़ना नहीं चाहते हैं, तो बस विधि के स्रोत कोड की प्रतिलिपि बनाएँ StringUtils#equalsऔर इसे ज़रूरत पड़ने पर लागू करें।


28

Android पर उन लोगों के लिए, जो API 19 के Objects.equals (str1, str2) का उपयोग नहीं कर सकते हैं, यह है:

android.text.TextUtils.equals(str1, str2);

यह शून्य सुरक्षित है। इसे शायद ही कभी अधिक महंगे string.equals () विधि का उपयोग करना पड़ता है क्योंकि Android पर समान तार लगभग हमेशा "==" के साथ तुलना करते हैं, जो एंड्रॉइड के स्ट्रिंग पूलिंग के लिए ऑपरेंड धन्यवाद है , और लंबाई की जांच सबसे बेमेल को छानने का एक तेज़ तरीका है।

सोर्स कोड:

/**
 * Returns true if a and b are equal, including if they are both null.
 * <p><i>Note: In platform versions 1.1 and earlier, this method only worked  well if
 * both the arguments were instances of String.</i></p>
 * @param a first CharSequence to check
 * @param b second CharSequence to check
 * @return true if a and b are equal
 */
public static boolean equals(CharSequence a, CharSequence b) {
    if (a == b) return true;
    int length;
    if (a != null && b != null && (length = a.length()) == b.length()) {
        if (a instanceof String && b instanceof String) {
            return a.equals(b);
        } else {
            for (int i = 0; i < length; i++) {
                if (a.charAt(i) != b.charAt(i)) return false;
            }
            return true;
        }
    }
    return false;
}

7

चूंकि संस्करण 3.5 अपाचे कॉमन्स स्ट्रिंग स्ट्रिंग में निम्नलिखित तरीके हैं:

static int  compare(String str1, String str2)
static int  compare(String str1, String str2, boolean nullIsLess)
static int  compareIgnoreCase(String str1, String str2)
static int  compareIgnoreCase(String str1, String str2, boolean nullIsLess)

ये अशक्त सुरक्षित स्ट्रिंग तुलना प्रदान करते हैं।


6

जावा 8 का उपयोग करना :

private static Comparator<String> nullSafeStringComparator = Comparator
        .nullsFirst(String::compareToIgnoreCase); 

private static Comparator<Metadata> metadataComparator = Comparator
        .comparing(Metadata::getName, nullSafeStringComparator)
        .thenComparing(Metadata::getValue, nullSafeStringComparator);

public int compareTo(Metadata that) {
    return metadataComparator.compare(this, that);
}

4

समतुल्य (-, -) और equalsIgnoreCase (-, -) पद्धति का उपयोग करते हुए अपाचे कॉमन्स स्ट्रिंजटिल्स वर्ग की दो स्ट्रिंग की तुलना करें।

StringUtils.equals (-, -) :

StringUtils.equals(null, null)   = true
StringUtils.equals(null, "abc")  = false
StringUtils.equals("abc", null)  = false
StringUtils.equals("abc", "abc") = true
StringUtils.equals("abc", "ABC") = false

StringUtils.equalsIgnoreCase (-, -) :

StringUtils.equalsIgnoreCase(null, null)   = true
StringUtils.equalsIgnoreCase(null, "abc")  = false
StringUtils.equalsIgnoreCase("xyz", null)  = false
StringUtils.equalsIgnoreCase("xyz", "xyz") = true
StringUtils.equalsIgnoreCase("xyz", "XYZ") = true


2
boolean compare(String str1, String str2) {
    if(str1==null || str2==null) {
        //return false; if you assume null not equal to null
        return str1==str2;
    }
    return str1.equals(str2);
}

क्या यह आप चाहते हैं?


5
यह मामला लौटता है falseअगर दोनों स्ट्रिंग्स हैं nullजो वांछित परिणाम नहीं हो सकते हैं।
JScoobyCed

1
boolean compare(String str1, String str2) {
    if (str1 == null || str2 == null)
        return str1 == str2;

    return str1.equals(str2);
}


0

ठीक है, तो "सबसे अच्छा संभव समाधान" का क्या मतलब है?

यदि आप सबसे अधिक पठनीय हैं, तो सभी संभावित समाधान एक अनुभवी जावा प्रोग्रामर के लिए बहुत अधिक समकक्ष हैं। लेकिन IMO सबसे पठनीय है

 public boolean compareStringsOrNulls(String str1, String str2) {
     // Implement it how you like
 }

दूसरे शब्दों में, कार्यान्वयन को एक सरल विधि के अंदर छिपाएं जो (आदर्श रूप से) अंतर्निर्मित हो सकती है।

(आप तृतीय पक्ष उपयोगिता लाइब्रेरी को "आउट-सोर्स" भी कर सकते हैं ... यदि आप पहले से ही अपने कोडबेस में इसका उपयोग करते हैं।)


यदि आप सबसे अधिक प्रदर्शन करने वाले हैं, तो:

  1. सबसे अच्छा समाधान मंच और संदर्भ पर निर्भर करता है,
  2. "संदर्भ" मुद्दों में से एक nullतर्क की घटना के सापेक्ष (गतिशील) आवृत्ति है ,
  3. यह संभवत: कोई फर्क नहीं पड़ता कि कौन सा संस्करण तेज है ... क्योंकि अंतर शायद समग्र अनुप्रयोग प्रदर्शन के लिए एक अंतर बनाने के लिए बहुत छोटा है, और
  4. अगर यह मायने रखता है, तो यह पता लगाने का एकमात्र तरीका है कि आपके प्लेटफॉर्म पर सबसे तेज़ है दोनों संस्करणों की कोशिश करें और अंतर को मापें।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.