लूप के लिए एक बढ़ाया में अशक्त चेक


172

जावा में लूप के लिए अशक्त से बचाव का सबसे अच्छा तरीका क्या है?

यह बदसूरत लगता है:

if (someList != null) {
    for (Object object : someList) {
        // do whatever
    }
}

या

if (someList == null) {
    return; // Or throw ex
}
for (Object object : someList) {
    // do whatever
}

कोई और रास्ता नहीं हो सकता है। क्या उन्हें इसे forस्वयं निर्माण में लगाना चाहिए, यदि यह अशक्त है तो लूप न चलाएं?


2
आप शायद एक एनपीई फेंकने से बेहतर हैं। nullएक खाली संग्रह के समान नहीं है।
टॉम हॉकिन -

6
@GregMattes फरवरी का प्रश्न अक्टूबर के प्रश्न का डुप्लिकेट कैसे है?
वैल

1
बस Collections.nonNullElementsIn (...) का उपयोग करने की आवश्यकता है: stackoverflow.com/a/34913556/5637185
जेफरी डिले

जवाबों:


227

आपको बेहतर सत्यापन करना चाहिए कि आपको वह सूची कहां से मिली है।

खाली सूची आपको चाहिए, क्योंकि खाली सूची विफल नहीं होगी।

यदि आपको यह सूची कहीं और से मिलती है और यह नहीं पता है कि यह ठीक है या नहीं, तो आप एक उपयोगिता विधि बना सकते हैं और इसे इस तरह उपयोग कर सकते हैं:

for( Object o : safe( list ) ) {
   // do whatever 
 }

और निश्चित रूप से safeहोगा:

public static List safe( List other ) {
    return other == null ? Collections.EMPTY_LIST : other;
}

57
ध्यान दें कि Collections.emptyList () एक अतिरिक्त ऑब्जेक्ट (IIRC) आवंटित करने से बचेंगी।
जॉन स्कीट

7
@Jon: मैंने हमेशा अपने आप से पूछा है, उस emptyList java.sun.com/j2se/1.5.0/docs/api/java/util/… व्हाट्स आईआईआरसी का उपयोग क्या था ?
OscarRyz

11
IIRC = "यदि मैं सही ढंग से याद करता हूं"। और हां, एक सिंगलटन उदाहरण है जो सभी कॉल के लिए कलेक्शन के लिए वापस किया जाता है। खाली सूची ()।
कॉलिनड

यह ... वास्तव में इस सवाल का जवाब नहीं है। क्यों स्वीकार किया जाता है उत्तर?
क्रिस्टोफर विर्ट

1
@ChristopherWirt क्योंकि यह प्रश्न का उत्तर देता है: D
तारिक

100

आप संभावित रूप से एक सहायक विधि लिख सकते हैं जो शून्य में पारित होने पर खाली क्रम लौटाता है:

public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
    return iterable == null ? Collections.<T>emptyList() : iterable;
}

फिर उपयोग करें:

for (Object object : emptyIfNull(someList)) {
}

मुझे नहीं लगता कि मैं वास्तव में ऐसा करूंगा - हालांकि मैं आमतौर पर आपके दूसरे फॉर्म का उपयोग करता हूं। विशेष रूप से, "थ्रो एक्स" महत्वपूर्ण है - यदि यह वास्तव में अशक्त नहीं होना चाहिए, तो आपको निश्चित रूप से एक अपवाद फेंकना चाहिए। आप जानते हैं कि कुछ गलत हो गया है, लेकिन आप नुकसान की सीमा नहीं जानते हैं। जल्दी गर्भपात कराएं।


3
मैं Iterable <T> सूची पैरामीटर को Iterable <T> iterable में बदल दूंगा, क्योंकि प्रत्येक चलने योग्य सूची नहीं है।
लोम्बो

इस विधि का उपयोग करने में सावधानी बरतें: क्योंकि सामूहिक वर्ग के उपयोग के कारण, इस विधि के प्रयोग में आपकी सूची शामिल नहीं हो सकती है
Tanorix

@tanorix: किस तरह से?
जॉन स्कीट

@JonSkeet आप देख सकते हैं कि कलेक्शन क्लास का खाली सूची () एक अपरिवर्तनीय सूची लौटाता है : docs.oracle.com/javase/8/docs/api/java/util/… इसलिए यदि उपयोगकर्ता नहीं चाहता है कि उसकी सूची अपरिवर्तनीय हो तो समस्याग्रस्त हो
Tanorix

@tanorix: लेकिन इस सवाल का बिंदु लौटे मूल्य से अधिक पुनरावृत्ति करने के बारे में है । वह इसे संशोधित नहीं करता है। इसलिए वापसी का प्रकार emptyIfNullहै Iterable<T>- वहाँ removeपर दुर्भाग्यपूर्ण विधि है Iterator<T>, लेकिन इसका केवल एक ही परिवर्तनशील पहलू है (और यदि आपको एक खाली संग्रह मिला है, तो आप इससे कुछ भी निकालने की कोशिश क्यों कर रहे हैं?) यह स्पष्ट नहीं है कि आप क्या हैं? ' यहां आपत्ति जताई।
जॉन स्कीट

29

यह पहले से ही 2017 है, और अब आप अपाचे कॉमन्स कलेक्शंस 4 का उपयोग कर सकते हैं

उपयोगितायें:

for(Object obj : ListUtils.emptyIfNull(list1)){
    // Do your stuff
}

आप अन्य संग्रह कक्षाओं के साथ एक ही अशक्त-सुरक्षित जाँच कर सकते हैं CollectionUtils.emptyIfNull


2
काम करेगा हालांकि अनावश्यक सूची वस्तु बनाता है। एक CollectionUtils.ifNotEmpty अधिक क्रिया हो सकती है लेकिन अधिक कुशल और तेज है। ऐसा नहीं है कि यह बहुत मायने रखेगा ...
लॉरेंस

2
2017 में मैं List.emptyIfNull (list1)
Dima

3
@ लॉरेंस, विधि नई सूची ऑब्जेक्ट नहीं बनाता है, यह Collections.emptyList()आंतरिक रूप से उपयोग करता है , जो अपनी बारी में हमेशा एक ही प्रचारित खाली unmodifiable सूची देता है।
योरी एन।

यदि आप myobject.getCompanies ()। GetAddresses () और दोनों एक सूची लौटाते हैं और दोनों अशक्त हो सकते हैं तो क्या होगा?
पाउडर 366

9

जावा 8 के साथ Optional:

for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList())) {
    // do whatever
}

1
साधारण टर्नरी ऑपरेटर की तुलना में इसकी क्रिया अधिक है someList != null ? someList : Collections.emptyList()और यह Optionalवस्तु का एक उदाहरण भी बनाता है और तुरंत फेंक देता है ।
योरी एन।

2
कैसे इन राक्षस लाइनों एक सरल से अधिक सुंदर हैं अगर (someList == अशक्त) बयान। आइए एक पंक्ति में एक बैंक आवेदन लिखें ...
एंड्रियास पनियागोटिडिस

8

Arrays के लिए पुस्तकालय ArrayUtils.nullToEmptyसे उपयोग करेंcommons-lang

for( Object o : ArrayUtils.nullToEmpty(list) ) {
   // do whatever 
}

यह कार्यक्षमता commons-langलाइब्रेरी में मौजूद है , जो कि अधिकांश जावा परियोजनाओं में शामिल है।

// ArrayUtils.nullToEmpty source code 
public static Object[] nullToEmpty(final Object[] array) {
    if (isEmpty(array)) {
        return EMPTY_OBJECT_ARRAY;
    }
    return array;
}

// ArrayUtils.isEmpty source code
public static boolean isEmpty(final Object[] array) {
    return array == null || array.length == 0;
}

यह @OscarRyz द्वारा दिए गए उत्तर के समान है, लेकिन DRY मंत्र के लिए, मेरा मानना ​​है कि यह ध्यान देने योग्य है। देखें कॉमन्स-लैंग परियोजना पृष्ठ। यहाँ nullToEmptyएपीआई प्रलेखन और स्रोत है

commons-langअपने प्रोजेक्ट में शामिल करने के लिए मावेन प्रविष्टि यदि यह पहले से ही नहीं है।

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.4</version>
</dependency>

दुर्भाग्य से, commons-langयह कार्यक्षमता Listप्रकारों के लिए प्रदान नहीं करता है । इस मामले में आपको पहले बताए अनुसार एक सहायक विधि का उपयोग करना होगा।

public static <E> List<E> nullToEmpty(List<E> list)
{
    if(list == null || list.isEmpty())
    {
        return Collections.emptyList();
    }
    return list;
}

7

यदि आपको लगता Listहै कि आपके द्वारा लागू की गई एक विधि कॉल से, तो वापस न करें null, खाली लौटें List

यदि आप कार्यान्वयन को बदल नहीं सकते हैं तो आप nullचेक के साथ फंस गए हैं । यदि यह नहीं होना चाहिए null, तो एक अपवाद फेंक दें।

मैं सहायक विधि के लिए नहीं जाऊंगा जो एक खाली सूची देता है क्योंकि यह कुछ समय के लिए उपयोगी हो सकता है लेकिन फिर आपको इसे हर लूप में कॉल करने की आदत होगी जो आप संभवतः कुछ बग छिपाते हैं।


4

मैंने उपरोक्त उत्तर को संशोधित किया है, इसलिए आपको ऑब्जेक्ट से कास्ट करने की आवश्यकता नहीं है

public static <T> List<T> safeClient( List<T> other ) {
            return other == null ? Collections.EMPTY_LIST : other;
}

और फिर बस सूची को कॉल करें

for (MyOwnObject ownObject : safeClient(someList)) {
    // do whatever
}

स्पष्टीकरण: MyOwnObject: यदि List<Integer>तब MyOwnObject इस मामले में पूर्णांक होगा।


1

एक लूप के लिए एक अशक्त के खिलाफ प्रभावी ढंग से पहरा देने का दूसरा तरीका यह है कि आप अपने संग्रह को Google अमरूद के साथ लपेटें Optional<T>, क्योंकि यह उम्मीद करता है कि प्रभावी रूप से खाली संग्रह की संभावना स्पष्ट हो जाती है क्योंकि ग्राहक को यह जांचने की उम्मीद होगी कि क्या संग्रह के साथ मौजूद है Optional.isPresent()


1

किसी के लिए अपने स्वयं के स्थिर अशक्त सुरक्षा विधि का उपयोग करने में उदासीन आप उपयोग कर सकते हैं: कॉमन्स-लैंग के org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object)। उदाहरण के लिए:

    for (final String item : 
    (List<String>)ObjectUtils.defaultIfNull(items, Collections.emptyList())) { ... }

ObjectUtils.defaultIfNull JavaDoc


मेरे लिए, यह उत्तर सबसे सुरुचिपूर्ण है
Truong Nguyen

0

CollectionUtils.isEmpty(Collection coll)यदि निर्दिष्ट संग्रह खाली है तो प्रयोग करें, विधि जो अशक्त-सुरक्षित है।

इसके लिए import org.apache.commons.collections.CollectionUtils

मावेन निर्भरता

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.0</version>
</dependency>

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