java - जावा 8 सूची प्रसंस्करण-तत्वों को सशर्त रूप से जोड़ें




collections java-8 (4)

आप addAll के रिटर्न मान को जांचने का प्रयास कर सकते हैं। जब भी सूची को संशोधित किया गया है, यह true हो जाएगा, इसलिए यह प्रयास करें:

List<Object> list = new ArrayList<>();
// ret unused, otherwise it doesn't compile
boolean ret = list.addAll(method1())
    || list.addAll(method2()) 
    || list.addAll(method3())
    || list.addAll(method4())
    || list.addAll(method5())
    || list.addAll(method6());
return list;

आलसी मूल्यांकन के कारण, कम से कम एक तत्व को जोड़ने वाला पहला addAll ऑपरेशन बाकी को बीइन कहे जाने से रोक देगा। मुझे यह तथ्य पसंद है कि "" || मंशा को अच्छी तरह से व्यक्त करता है।

मेरे पास निम्नलिखित कोड है:

List<Object> list = new ArrayList<>();
list.addAll(method1());
if(list.isEmpty()) { list.addAll(method2()); }
if(list.isEmpty()) { list.addAll(method3()); }
if(list.isEmpty()) { list.addAll(method4()); }
if(list.isEmpty()) { list.addAll(method5()); }
if(list.isEmpty()) { list.addAll(method6()); }
return list;

क्या सशर्त रूप से तत्वों को जोड़ने का एक अच्छा तरीका है, शायद धारा संचालन का उपयोग करना? मैं मेथड 2 से तत्वों को जोड़ना चाहूंगा, अगर सूची खाली है अन्यथा वापस लौटें और इसी तरह।

संपादित करें: यह उल्लेख के लायक है कि विधियों में भारी तर्क शामिल हैं इसलिए निष्पादन से रोकने की आवश्यकता है।


आप इस तरह से एक विधि बना सकते हैं:

public static List<Object> lazyVersion(Supplier<List<Object>>... suppliers){
      return Arrays.stream(suppliers)
                .map(Supplier::get)
                .filter(s -> !s.isEmpty()) // or .filter(Predicate.not(List::isEmpty)) as of JDK11
                .findFirst()
                .orElseGet(Collections::emptyList);
}

और फिर इसे निम्नानुसार कॉल करें:

lazyVersion(() -> method1(),
            () -> method2(),
            () -> method3(),
            () -> method4(),
            () -> method5(),
            () -> method6());

केवल चित्रण प्रयोजनों के लिए विधि का नाम।


खुद को दोहराए बिना इसे करने का एक तरीका यह है कि आप इसके लिए एक तरीका निकालें:

private void addIfEmpty(List<Object> targetList, Supplier<Collection<?>> supplier) {
    if (targetList.isEmpty()) {
        targetList.addAll(supplier.get());
    }
}

और तब

List<Object> list = new ArrayList<>();
addIfEmpty(list, this::method1);
addIfEmpty(list, this::method2);
addIfEmpty(list, this::method3);
addIfEmpty(list, this::method4);
addIfEmpty(list, this::method5);
addIfEmpty(list, this::method6);
return list;

या लूप के लिए भी उपयोग करें:

List<Supplier<Collection<?>>> suppliers = Arrays.asList(this::method1, this::method2, ...);
List<Object> list = new ArrayList<>();
suppliers.forEach(supplier -> this.addIfEmpty(list, supplier));

अब DRY सबसे महत्वपूर्ण पहलू नहीं है। अगर आपको लगता है कि आपका मूल कोड पढ़ना और समझना आसान है, तो इसे ऐसे ही रखें।


मैं केवल सप्लायर्स की एक स्ट्रीम का उपयोग करूंगा और List.isEmpty पर फ़िल्टर List.isEmpty :

Stream.<Supplier<List<Object>>>of(() -> method1(), 
                                  () -> method2(), 
                                  () -> method3(), 
                                  () -> method4(), 
                                  () -> method5(), 
                                  () -> method6())
    .map(Supplier<List<Object>>::get)
    .filter(l -> !l.isEmpty())
    .findFirst()
    .ifPresent(list::addAll);

return list;

findFirst() पहले गैर-खाली सूची विधियों में से किसी एक के वापस findFirst() को अनावश्यक कॉल को रोक देगा।

संपादित करें:
जैसा कि नीचे दी गई टिप्पणियों में कहा गया है, यदि आपकी list ऑब्जेक्ट को किसी और चीज़ के साथ आरंभीकृत नहीं किया गया है, तो यह केवल धारा के परिणाम को वापस करने के लिए समझ में आता है:

return  Stream.<Supplier<List<Object>>>of(() -> method1(), 
                                          () -> method2(), 
                                          () -> method3(), 
                                          () -> method4(), 
                                          () -> method5(), 
                                          () -> method6())
    .map(Supplier<List<Object>>::get)
    .filter(l -> !l.isEmpty())
    .findFirst()
    .orElseGet(ArrayList::new);




java-stream