2015-10-25 4 views
6

मैं सिर्फ lamdas जावा अभ्यास कर रहा हूँ 8. मेरे समस्या के रूप में अपनी कम से कम 10 तक एक पूर्णांक में सभी अंकसंख्या के अंकों का योग रिकर्सिव जावा 8 lambdas (जब तक अंकों कम से कम 10 है) केवल

योग इस प्रकार है और चेक (एकल अंक बाईं मतलब है) अगर इसकी 1

नमूना इनपुट 1

100 

नमूना आउटपुट 1

1 // true because its one 

नमूना इनपुट 2

55 

नमूना आउटपुट 2

1  ie 5+5 = 10 then 1+0 = 1 so true 

मैं एक कोड

System.out.println(Arrays.asList(String.valueOf(number).split("")).stream() 
                    .map(Integer::valueOf) 
                    .mapToInt(i->i) 
                    .sum() == 1); 

यह इनपुट 1 यानी 100 के लिए काम करता लिखा था लेकिन इनपुट 2 यानी 55 के लिए नहीं, जो मैं स्पष्ट रूप से समझता हूं कि दूसरे मामले में 10 आउटपुट है क्योंकि पुनरावृत्ति रिकर्सिव नहीं है।

तो मैं इस लैम्ब्स अभिव्यक्ति को रिकर्सिव कैसे बना सकता हूं ताकि यह दूसरे मामले में भी काम कर सके? मैं उस लैम्ब्डा अभिव्यक्ति के साथ एक विधि बना सकता हूं और इसे हर बार कॉल कर सकता हूं जब तक वापसी मूल्य < 10 नहीं है लेकिन मैं सोच रहा था कि लैम्बडास के भीतर कोई दृष्टिकोण है या नहीं।

धन्यवाद

+2

आपका पूरा ऑपरेशन 'number.codePoints()। नक्शा (कैरेक्टर :: getNumericValue) .sum()' के लिए सरलीकृत किया जा सकता है, लेकिन आप नामित विधि के बिना इसे रिकर्सिव नहीं बना सकते हैं। – Holger

+0

@ होल्गर नामित विधि के बिना रिकर्सिव लैम्बडा बनाने के [तरीके] (http://stackoverflow.com/q/19429667/335858) हैं। हालांकि, उन्हें नामित चर की आवश्यकता होती है। – dasblinkenlight

+1

@dasblinkenlight: लेकिन एक नामित विधि के बजाय नामित चर का उपयोग करने से कोई फायदा नहीं मिलता है, लेकिन सामान्य रिकर्सन की तुलना में प्रत्येक रिकर्सिव चरण में अतिरिक्त स्टैक फ्रेम का उत्पादन करता है ... – Holger

उत्तर

7

आप एक शुद्ध लैम्ब्डा समाधान चाहते हैं, तो आप, यह पुनरावर्ती बनाने के बारे में भूल जाने पर वहाँ बिल्कुल एक प्रत्यावर्तन के रूप में एक सतत प्रक्रिया लागू करने के लिए कोई कारण नहीं है:

Stream.iterate(String.valueOf(number), 
       n -> String.valueOf(n.codePoints().map(Character::getNumericValue).sum())) 
     .filter(s -> s.length()==1) 
     .findFirst().ifPresent(System.out::println); 

Demo

3

जावा में lambdas पुनरावर्ती बनाना "चर अप्रारंभीकृत जा सकता है" त्रुटि के कारण आसान नहीं है, लेकिन यह किया जा सकता है। यहां एक link to an answer describing one way of doing it है।

जब अपने कार्य के लिए आवेदन किया, इस इस प्रकार किया जा सकता है:

// This comes from the answer linked above 
class Recursive<I> { 
    public I func; 
} 

public static void main (String[] args) throws java.lang.Exception { 
    Recursive<Function<Integer,Integer>> sumDigits = new Recursive<>(); 
    sumDigits.func = (Integer number) -> { 
     int s = Arrays.asList(String.valueOf(number).split("")) 
      .stream() 
      .map(Integer::valueOf) 
      .mapToInt(i->i) 
      .sum(); 
     return s < 10 ? s : sumDigits.func.apply(s); 
    }; 
    System.out.println(sumDigits.func.apply(100) == 1); 
    System.out.println(sumDigits.func.apply(101) == 1); 
    System.out.println(sumDigits.func.apply(55) == 1); 
    System.out.println(sumDigits.func.apply(56) == 1); 
} 

मैं अपने कोड ले लिया, { में लपेटा ... } है, और return लाइन पर एक पुनरावर्ती मंगलाचरण गयी।

Demo.

+1

चूंकि समस्या रिकर्सिव नहीं है, मैंने एक बहुत ही सरल समाधान जोड़ा। जहां तक ​​मैं देख सकता हूं, लैम्बडास रिकर्सिव बनाने के बारे में अधिकतर प्रश्न वास्तव में एक एक्सवाई समस्या है। – Holger

+0

@ होल्गर मुझे बहुत संदेह है कि लोग रिकर्सिव लैम्बडास के साथ वास्तविक समस्याओं को हल करने की कोशिश कर रहे हैं मुझे लगता है कि रिकर्सिव लैम्बडास के बारे में अधिकतर प्रश्न शुद्ध जिज्ञासा से प्रेरित होते हैं: प्रोग्रामर जो एक नए और रोमांचक उपकरण सीख रहे हैं, स्वाभाविक रूप से यह देखने की कोशिश कर रहे हैं कि वे इसे कितनी दूर धक्का दे सकते हैं। जैसा कि यह निकलता है, कोई इसे बहुत दूर धक्का दे सकता है: -) – dasblinkenlight

+1

लेकिन ये प्रयास गलत दिशा में ले जाते हैं। जो लोग अब तक चीजों को धक्का देते हैं, वे असली जीवन कोड में एक ही अनावश्यक जटिल समाधान का उपयोग करते हैं। मैंने ऐसा कोड देखा है ... – Holger

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