2014-07-11 25 views
12

मैं यह पता लगाने की कैसे एक लैम्ब्डा अभिव्यक्ति से एक विधि मान देने के लिए कोशिश कर रहा हूँ के भीतर एक विधि से एक मूल्य के रिटर्निंग:एक लैम्ब्डा अभिव्यक्ति

public int findMissingNumber(Collection<Integer> ints) { 
    Single<Integer> start = new Single<>(1); 
    ints.stream().mapToInt(Integer::valueOf).parallel().forEach(i -> { 
     if (i != start.setValue(start.getValue() + 1)) { 
      //return here 
     } 
    }); 
    return -1; 
} 

हालांकि, ऐसा लगता है कि लैम्ब्डा में return कीवर्ड का उपयोग अभिव्यक्ति स्पष्ट रूप से लैम्ब्डा फ़ंक्शन पर वापस आ जाएगी। क्या पूरी विधि के लिए वापसी को तोड़ने या मजबूर करने का कोई तरीका है?

+1

आप वापस क्या करना चाहते हैं? यदि आप स्ट्रीम के सदस्य को वापस कर रहे हैं जो कुछ शर्त को पूरा करता है, तो फ़िल्टर का उपयोग करें। – Eran

उत्तर

15

क्या पूरे तरीके के लिए वापसी को तोड़ने या मजबूर करने का कोई तरीका है?

नहीं। कम से कम, जब तक कि आप कोई अपवाद नहीं फेंकते।

असल, कि क्या forEach के लिए है नहीं है। आप एक तरीका है जिसके एक समारोह जो "जारी रखने" और के लिए गैर-शून्य के लिए null वापसी होगी स्वीकार किए जाते हैं लिख सकता है "बंद करो, और यह परिणाम बनाने के" ... लेकिन उस विधि forEach नहीं है।

तथ्य यह है कि आप एक लैम्ब्डा अभिव्यक्ति का उपयोग कर रहे यहां वास्तव में आकस्मिक है। कल्पना कीजिए कि आप बस forEach पर कॉल कर रहे थे और कुछ तर्क में गुजर रहे थे - क्या यह वास्तव में अजीब नहीं होगा अगर उस कॉल ने findMissingNumber विधि वापसी (अपवाद के बिना) findMissingNumber विधि के बिना वापसी विवरण दिया है?

+0

मुझे लगता है कि मुख्य कारण मैं 'forEach' का उपयोग कर रहा था और शुरू करने के लिए स्ट्रीम 'समांतर' का उपयोग होगा (क्योंकि यह एक बड़े संग्रह के माध्यम से जा रहा है)। क्या आप इस तरह की धारा के माध्यम से जाने के लिए विधि/कार्य करने के "कैसे" पर विस्तार करने में सक्षम होंगे? – Rogue

+4

@Rogue: ठीक है, आप संभवतः इसे 'फ़िल्टर()' और 'findFirst()' के साथ बना सकते हैं - अपना 'फ़िल्टर' अनुमान बनाएं केवल "मिलान" वाले आइटम लौटाएं और फिर उस स्ट्रीम का पहला तत्व ढूंढें। दूसरी तरफ, आपके लैम्ब्डा अभिव्यक्ति में वर्तमान में एक दुष्प्रभाव है ('start.setValue() ') जो समांतरता के लिए एक अच्छा प्रारंभिक बिंदु नहीं है ... –

+0

ऐसा लगता है कि यह पर्याप्त साफ है, हालांकि मुझे लगता है कि यह थोड़ा सा है निराश होने से पहले पाए गए घटना से रोकने का कोई तरीका नहीं है (अपवाद फेंकना या तो लैम्ब्डा से बचने के लिए प्रतीत नहीं होता है)। धन्यवाद! – Rogue

11

(XY problem के इस एक उदाहरण है)

सवाल यह है कि एक लैम्ब्डा से एक forEach अंदर वापस जाने के लिए के बारे में है। दोनों उत्कृष्ट अंक - Jon Skeet कुछ उपयोगी जानकारी findFirst के बारे में है और यह भी समानांतर में एक लैम्ब्डा समय में दुष्प्रभावों के बारे में आगाह किया प्रदान की है।

लेकिन मूल प्रश्न के बारे में, मैं अभी भी सोच रहा हूँ: क्या समस्या को हल करने की कोशिश कर रहे हैं?

विधि नाम findMissingNumber उदाहरण में विचारोत्तेजक है। विधि काउंटर को बढ़ाने के दौरान पैरामीटर के रूप में संख्याओं का संग्रह लेती है और इसके ऊपर पुनरावृत्त करती है। जब यह मेल नहीं खाता है तो यह लौटाता है, या यदि कोई मेल नहीं खाता है तो यह -1 लौटाता है। चूंकि काउंटर को एक बार बढ़ाया जाता है क्योंकि ints संग्रह में प्रत्येक मान संसाधित होता है, ऐसा लगता है कि उस संग्रह को क्रम में होने की उम्मीद है, जब तक कि कोई संख्या गुम न हो।

यदि ऐसा है, तो पैरामीटर Collection के बजाय List होना चाहिए। (। यहाँ एक बड़ा धारणा बनाना) इस धारणा के तहत, एक lambdas का उपयोग कर कोड को फिर से लिखने सका, इसलिए जैसे धाराओं के रूप में:

static OptionalInt findMissingNumber(List<Integer> ints) { 
    return 
     IntStream.rangeClosed(1, ints.size()) 
      .filter(i -> i != ints.get(i-1)) 
      .findFirst(); 
} 

बजाय एक काउंटर incrementing की, हम IntStream.range का उपयोग मान सूची में होने की उम्मीद उत्पन्न करने के लिए । फिर हम सूची में उनकी अपेक्षित स्थिति से get मूल्यों की सूची में यादृच्छिक पहुंच पर भरोसा करते हैं। हम विसंगतियों के लिए फ़िल्टर करते हैं और पहले किसी को वापस लौटाते हैं। यह उत्परिवर्तन से बचाता है और इसलिए समानांतर में सही ढंग से चलना चाहिए। (ध्यान दें कि यह अच्छी तरह से हालांकि parallelize नहीं करता है तो सूची यादृच्छिक अभिगम नहीं है।)

वापसी मान एक OptionalInt जो खाली है अगर कोई बेमेल पाया गया है। "नहीं मिला" स्थिति इंगित करने के लिए -1 जैसे सेंटीनेल मान का उपयोग करने से यह अधिक स्पष्ट है।

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