मैं किसी ऐरे से स्ट्रीम कैसे बना सकता हूं?


133

वर्तमान में जब भी मुझे किसी ऐरे से स्ट्रीम बनाने की आवश्यकता होती है, मैं करता हूं

String[] array = {"x1", "x2"};
Arrays.asList(array).stream();

क्या किसी सरणी से स्ट्रीम बनाने का कोई सीधा तरीका है?

जवाबों:


201

आप Arrays.stream एग का उपयोग कर सकते हैं

Arrays.stream(array);

आप Stream.of@fge द्वारा बताए अनुसार उपयोग कर सकते हैं , जो दिखता है

public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

लेकिन टिप्पणी Stream.of(intArray)वापस आ जाएगी Stream<int[]>, जबकि Arrays.stream(intArr)वापस आ जाएगी IntStreamआप प्रकार की एक सरणी पारित उपलब्ध कराने के int[]। तो आदिम प्रकार के लिए संक्षेप में आप 2 तरीकों के बीच अंतर देख सकते हैं

int[] arr = {1, 2};
Stream<int[]> arr1 = Stream.of(arr);

IntStream stream2 = Arrays.stream(arr); 

जब आप आदिम सरणी को पास करते हैं Arrays.stream, तो निम्न कोड का उपयोग किया जाता है

public static IntStream stream(int[] array) {
    return stream(array, 0, array.length);
}

और जब आप Stream.ofनिम्नलिखित कोड के लिए आदिम सरणी पास करते हैं, तो इसे लागू किया जाता है

 public static<T> Stream<T> of(T t) {
     return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
 }

इसलिए आपको अलग-अलग परिणाम मिलते हैं।

अपडेट किया गया : स्टुअर्ट मार्क्स द्वारा उल्लेखित टिप्पणी के अनुसार, ओवरग्राउंड ओवरलोड का Arrays.streamउपयोग करना बेहतर होता है Stream.of(array).skip(n).limit(m)क्योंकि पूर्व परिणाम एक सीजेड स्ट्रीम में होता है जबकि बाद वाला नहीं होता है। इसका कारण यह है कि limit(m)पता नहीं है कि आकार मीटर से कम है या मीटर से कम है, जबकि Arrays.streamसीमा की जाँच करता है और स्ट्रीम का सटीक आकार जानता है। आप स्ट्रीम कोड लागू करने के लिए स्रोत कोड Arrays.stream(array,start,end) यहाँ से पढ़ सकते हैं , जबकि स्ट्रीम कार्यान्वयन के लिए वापस आ गया Stream.of(array).skip().limit()है। इस विधि के भीतर ।


9
यह उत्तर बेहतर है क्योंकि Arrays.streamआदिम सरणियों के लिए सभी अतिभारित मामले हैं। Ie Stream.of(new int[]{1,2,3})आपको थोड़ी Stream<int[]>देर Arrays.streamदेगा आपको वापस दे देगा IntStreamजो शायद आप चाहते हैं। तो +1
user2336315

3
@ मुझे लगता है कि यह स्वाद की बात है। मेरा मतलब है कि एक अर्थ में बेहतर Stream.ofआपको कुछ आश्चर्य दे सकता है (जैसे कि जब आप Arrays.asListएक आदिम सरणी के साथ कॉल करते हैं और लोग एक List<Integer>पीठ की उम्मीद करते हैं) :-)
user2336315

3
Arrays.streamसरणी की एक श्रेणी स्ट्रीमिंग का समर्थन करता है, जो IntStream.ofनहीं करता है। इसके विपरीत, Stream.ofयदि आप एक आकार चाहते हैं तो बेहतर विकल्प है ...Stream<int[]>1
Holger

4
@ डिमा का उपरिव्यय अधिभार Arrays.streamउपयोग करने के लिए बेहतर है Stream.of(array).skip(n).limit(m)क्योंकि पूर्व परिणाम एक सीज़्ड स्ट्रीम में होता है जबकि बाद में नहीं होता है। कारण यह है कि limit(m)पता नहीं है कि आकार की mतुलना में कम है या कम है m, जबकि Arrays.streamसीमा की जांच करता है और स्ट्रीम के सटीक आकार को जानता है।
स्टुअर्ट मार्क्स

6
पाठकों ने इस छोटे से नाटक संपन्न हुआ देखने में रुचि रखने के लिए, Arrays.stream(array,start,end)वापस आने वाले Streamजिसका कार्यान्वयन है यहाँ , जबकि Stream.of(array).skip().limit()रिटर्न एक Streamजिसका कार्यान्वयन के भीतर है इस विधि
स्टुअर्ट मार्क्स

43

@ Sol4me के समाधान के लिए वैकल्पिक:

Stream.of(theArray)

इस और इस अंतर के बीच Arrays.stream(): यह फर्क पड़ता है अगर आपका सरणी एक आदिम प्रकार का है। उदाहरण के लिए, यदि आप करते हैं:

Arrays.stream(someArray)

जहां someArrayहै long[], वह वापस आ जाएगा LongStreamStream.of()दूसरी ओर, Stream<long[]>एक एकल तत्व के साथ वापस आ जाएगा ।


1
@ डिमा ज़रूर, लेकिन उसके लिए भी Arrays.stream()काम करता है
fge

2
खैर, धाराओं के रूप में, सुविधा! *Stream.of()जब आप Arrays.stream()आदिम सरणियों के साथ काम करते हैं तो आपको कॉल करने की आवश्यकता नहीं होती है । और वास्तविक वस्तु नहीं होने के कारण सरणियों के रूप में, ठीक है, यह जावा है, यह 1.0 के बाद से ऐसा मामला रहा है; इस पर ब्रूडिंग कुछ भी करने में मदद करता है
16

2
@ दीमा और इसी तरह तुम्हारा है; आपArrays.stream() सुविधाजनक नहीं मानते हैं, मैं इसे सुविधाजनक मानता हूं । पर्याप्त कथन।
fge

2
@ दीमा जी, मुझे आपका तर्क ऐसा लगता है, जो सहज *Stream.of()होने के लिए अधिक सुविधाजनक है; क्योंकि यह वरीयताओं का मामला है । मैं Arrays.stream()ऐसे मामलों के लिए पसंद करता हूं , जो सामान्य नियम के रूप में गलत है जो Stream.of()अधिक सुविधाजनक है (पीनो बीजगणित)।
फेज

3
@ दीमा: यह वरीयता की बात है। मतभेद इतने अविश्वसनीय रूप से छोटे हैं कि यह बिल्कुल भी मायने नहीं रखता है। अधिक विशेष रूप से: कुछ वर्णों का अंतर कुछ भी नहीं है । एक पैकेज पर एक अतिरिक्त आयात मानक पुस्तकालयों के अंदर है कुछ भी नहीं है । और वास्तव में, मैन्युअल रूप से एक varargs अधिभार के बजाय एक सरणी बनाना कुछ भी नहीं है
जीरो वेनवेल

14
Stream.of("foo", "bar", "baz")

या, यदि आपके पास पहले से ही एक सरणी है, तो आप भी कर सकते हैं

Stream.of(array) 

आदिम प्रकार के उपयोग IntStream.ofया LongStream.ofआदि के लिए


जो मुझे समझ नहीं आ रहा है, जब int[]एक विधि को वैराग्य को स्वीकार करने के लिए पारित किया जा सकता है, तो इसके बजाय Stream.of(intArray)उत्पादन क्यों नहीं होगा ? इसके अलावा, क्या कोई तकनीकी तर्क है कि आदिमों के लिए विशेष स्ट्रीम कक्षाएं क्यों हैं? Stream<Integer>Stream<int[]>
asgs

1
जावा आदिम अजीब जानवर हैं। int[]अन्य सरणियों की तरह नहीं है। इसके बारे में एक उपवर्ग नहीं है Object[], लेकिन यह है की एक उपवर्ग Object। इसलिए, जब आप इसे पास करते हैं Stream.of, तो इसे Objectपैरामीटर के रूप में लिया जाता है , और आपको इसकी एक धारा मिलती है int[]। आदिम के लिए विशेष कक्षाएं होने के कारणों में से एक है - यदि आप आदिम सरणियों से धाराएं नहीं बना रहे हैं तो यह बहुत दर्दनाक होगा। दूसरा कारण, यह है कि विशेष कक्षाएं अधिक कुशल होती हैं, क्योंकि Objectबॉक्सिंग से ओवरहेड को उकसाने की आवश्यकता नहीं होती है ( इसे सामान्य वस्तुओं की तरह बनाने के लिए परिवर्तित intकरना Integer)।
दिमा

आह, चूंकि int[]यह एक है Object, यह अतिभारित विधि से मेल खाता है of(T t)और इसलिए यह वापस आ जाता है Stream<int[]>। इसलिए, सैद्धांतिक रूप से, अगर यह तरीका उपलब्ध नहीं होता, तो हमें Stream<Integer>बदले में मिल जाता ? या शायद यह एक संकलन त्रुटि के कारण होता है क्योंकि यह मिलान विधि नहीं खोज सका? यानी int[]इलाज नहीं किया जा सकता हैT...
भीख देता है

1
नहीं, हम अभी भी Stream<Integer>उस तरह से नहीं मिलेंगे , क्योंकि Stream.of(t ... T) अभी भी उसी तरह से मेल खाएंगे।
दिमा

0

आप इसे निम्न स्तर की विधि से भी बना सकते हैं जिसमें समानांतर विकल्प हैं:

अद्यतन: पूर्ण array.length (लंबाई नहीं - 1) का उपयोग करें।

/** 
 * Creates a new sequential or parallel {@code Stream} from a
 * {@code Spliterator}.
 *
 * <p>The spliterator is only traversed, split, or queried for estimated
 * size after the terminal operation of the stream pipeline commences.
 *
 * @param <T> the type of stream elements
 * @param spliterator a {@code Spliterator} describing the stream elements
 * @param parallel if {@code true} then the returned stream is a parallel
 *        stream; if {@code false} the returned stream is a sequential
 *        stream.
 * @return a new sequential or parallel {@code Stream}
 *
 * <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel)
 */

StreamSupport.stream(Arrays.spliterator(array, 0, array.length), true)

0

आप Arrays.stream का उपयोग कर सकते हैं:

(सरणी) Arrays.stream; 

यह आपके सरणी इनपुट प्रकार के आधार पर स्टीम के रिटर्न प्रकार को सुनिश्चित करता है, यदि इसके String []बाद वापस लौटा Stream<String>, तो यदि int []रिटर्नIntStream

जब आप पहले से ही इनपुट प्रकार सरणी जानते हैं तो इनपुट प्रकार के लिए विशिष्ट एक का उपयोग करना अच्छा है int[]

 IntStream.of (सरणी); 

यह इंटस्ट्रीम देता है।

पहले उदाहरण में, जावा overloadingइनपुट प्रकारों के आधार पर विशिष्ट विधि खोजने के लिए विधि का उपयोग करता है जबकि दूसरे में आप इनपुट प्रकार और कॉलिंग विशिष्ट विधि को पहले से ही जानते हैं।


0

शायद ही कभी देखा गया हो, लेकिन यह सबसे सीधा तरीका है

Stream.Builder<String> builder = Stream.builder();
for( int i = 0; i < array.length; i++ )
  builder.add( array[i] );
Stream<String> stream = builder.build();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.