2016-04-05 31 views
6

के अनुसार प्रभावी जावा 2 एड, जब आप एक विधि हस्ताक्षर लिखना चाहते हैं जो varargs की अनुमति देता है लेकिन अभी भी लागू करता है कि आपके पास संकलन-समय पर कम से कम एक तत्व है, तो आपको विधि हस्ताक्षर लिखना चाहिए :जावा 8 स्ट्रीम और varargs

public void something(String required, String ... additional) { 
    Stream<String> allParams = 
     Stream.concat(Stream.of(required), Stream.of(additional)); 
    //... do what you want to do 
} 

यह वास्तव में असजीला और बेकार लगता है, विशेष रूप से, क्योंकि मैं 1 की एक धारा बना रहा हूं:

public void something(String required, String ... additional) { 
    //... do what you want to do 
} 

मैं इन सभी तत्वों स्ट्रीम करने के लिए चाहते हैं, तो मैं कुछ इस तरह कर रहा हूँ और concatena इसे दूसरे के साथ टिंग करें। क्या ऐसा करने का कोई क्लीनर तरीका है?

+5

'Stream.concat' मेरे लिए ठीक लग रहा है .. .it संक्षिप्त, संक्षेप में, यह डेटा की प्रतियां नहीं बनाता है। आप कुछ अतिरिक्त रैपर ऑब्जेक्ट्स बना रहे हैं, बस इतना ही। आईएमओ वास्तव में इसके साथ कुछ भी गलत नहीं है। जावा में प्रोग्रामिंग, आपको बस यहां और वहां चीजों के लिए छोटी वस्तुएं बनाना है। 'Stream.concat' पहले से ही' ArrayList' या उसके जैसा कुछ विलय करने से पहले मील आगे है। – Radiodef

+1

मैं रेडियोडेफ़ से सहमत हूं, यदि आप वास्तव में चाहते थे कि आप 'स्प्लिटरेटर ' का अपना कार्यान्वयन कर सकें और इसे 'StreamSupport.stream (spliterator, समानांतर)' के साथ उपयोग करें, लेकिन मुझे वास्तव में ऐसा नहीं लगता है कि यह और अधिक पठनीय या कुशल बनाता है । –

उत्तर

6

यहां दो Streams बनाने के बिना ऐसा करने का एक तरीका है, हालांकि आपको यह पसंद नहीं आएगा।

Stream.Builder<String> builder = Stream.<String>builder().add(required); 
for (String s : additional) { 
    builder.add(s); 
} 

Stream<String> allParams = builder.build(); 
+0

आप 'Stream.of (अतिरिक्त) के साथ फॉर-लूप को भी प्रतिस्थापित कर सकते हैं .forEach (builder); ' –

+0

इसे फिर से संशोधित करने और टिप्पणियों के आधार पर, मेरा मूल तरीका ठीक लगता है। हालांकि, यह जवाब मेरे पिछले दृश्य को दिया गया सबसे अच्छा विकल्प प्रतीत होता है। धन्यवाद :) –

1
सकता है

आप अमरूद उपयोग करने के लिए तैयार हैं, तो आप Lists.asList(required, additional).stream()। न्यूनतम आवश्यकता मुहावरे के साथ उस varargs को कम करने के लिए विधि बनाई गई थी।

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

2

दुर्भाग्यवश, जावा काफी वर्बोज़ हो सकता है। लेकिन इसे कम करने का एक और विकल्प केवल स्थिर आयात का उपयोग करना है। मेरी राय में, यह आपके कोड को कम स्पष्ट नहीं करता है क्योंकि प्रत्येक विधि धारा-संबंधित है।

Stream<String> allParams = 
    concat(of(required), of(additional)); 
1

रचनाकृत धाराओं में कुछ भी गलत नहीं है। ये ऑब्जेक्ट हल्के वजन वाले होते हैं क्योंकि वे केवल स्रोत डेटा का संदर्भ लेते हैं लेकिन सरणी सामग्री जैसे डेटा कॉपी नहीं करते हैं। इस तरह के हल्के ऑब्जेक्ट की लागत केवल तभी प्रासंगिक हो सकती है जब वास्तविक पेलोड भी बहुत छोटा हो। केवल एक ही तर्क है कि आप केवल Stream उदाहरणों लेकिन यह भी varargs सरणी (Stream.of के अधिभार के समान) नहीं बचत कर रहे हैं के मामले में तो

public void something(String required, String ... additional) { 
    somethingImpl(Stream.concat(Stream.of(required), Stream.of(additional))); 
} 
public void something(String required) { 
    somethingImpl(Stream.of(required)); 
} 
public void something(String required, String second) { 
    somethingImpl(Stream.of(required, second)); 
} 
private void somethingImpl(Stream<String> allParams) { 
    //... do what you want to do 
} 

: इस तरह के परिदृश्यों विशेष, शब्दार्थ बराबर भार के साथ संभाला जा सकता है। यह एक आम पैटर्न है, उदाहरण के लिए EnumSet.of ओवरलोड देखें।

हालांकि, कई मामलों में भी इन साधारण अधिभार आवश्यक नहीं हैं और उन्हें समयपूर्व अनुकूलन माना जा सकता है (जेआरई जैसे पुस्तकालय उन्हें ऑफर करते हैं क्योंकि किसी भी डेवलपर के लिए अन्यथा असंभव है, यदि कभी भी आवश्यकता हो)। यदि something लाइब्रेरी की बजाय किसी एप्लिकेशन का हिस्सा है, तो आपको उन्हें तब तक नहीं जोड़ना चाहिए जब तक कोई प्रोफाइलर आपको बताता है कि उस पैरामीटर प्रोसेसिंग के कारण कोई बाधा है।

1

तृतीय-पक्ष एक्सटेंशन की तरह मेरी StreamEx या jOOλappend या prepend जो आप और अधिक स्वच्छ तरीके से ऐसा करने की अनुमति की तरह के तरीकों प्रदान एपीआई स्ट्रीम करने के लिए:

// Using StreamEx 
Stream<String> allParams = StreamEx.of(required).append(additional); 
// Using jOOL 
Stream<String> allParams = Seq.of(required).append(additional); 
संबंधित मुद्दे