153

Currently whenever I need to create stream from an array, I do

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

Is there some direct way to create stream from an array?

0

6 Answers 6

220

You can use Arrays.stream E.g.

Arrays.stream(array);

You can also use Stream.of as mentioned by @fge , which looks like

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

But note Stream.of(intArray) will return Stream<int[]> whereas Arrays.stream(intArr) will return IntStream providing you pass an array of type int[]. So in a nutshell for primitives type you can observe the difference between 2 methods E.g.

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

IntStream stream2 = Arrays.stream(arr); 

When you pass primitive array to Arrays.stream, the following code is invoked

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

and when you pass primitive array to Stream.of the following code is invoked

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

Hence you get different results.

Updated: As mentioned by Stuart Marks comment The subrange overload of Arrays.stream is preferable to using Stream.of(array).skip(n).limit(m) because the former results in a SIZED stream whereas the latter does not. The reason is that limit(m) doesn't know whether the size is m or less than m, whereas Arrays.stream does range checks and knows the exact size of the stream You can read the source code for stream implementation returned by Arrays.stream(array,start,end) here, whereas for stream implementation returned by Stream.of(array).skip().limit() is within this method.

Sign up to request clarification or add additional context in comments.

21 Comments

This answer is better because Arrays.stream has all the overloaded cases for primitive arrays. I.e Stream.of(new int[]{1,2,3}) will give you a Stream<int[]> whereas Arrays.stream will give you back an IntStream which is probably what you want. So +1
@Dima I guess it's a matter of taste. I mean better in a sense Stream.of could give you some surprises (like when you call Arrays.asList with a primitive array and that people expect a List<Integer> back) :-)
Arrays.stream supports streaming a range of the array, which IntStream.of doesn’t. In contrast, Stream.of is the better choice if you want a Stream<int[]> of size 1
@Dima The subrange overload of Arrays.stream is preferable to using Stream.of(array).skip(n).limit(m) because the former results in a SIZED stream whereas the latter does not. The reason is that limit(m) doesn't know whether the size is m or less than m, whereas Arrays.stream does range checks and knows the exact size of the stream.
For readers who are interested in seeing this little drama concluded, Arrays.stream(array,start,end) returns a Stream whose implementation is here, whereas Stream.of(array).skip().limit() returns a Stream whose implementation is within this method.
|
44

Alternative to @sol4me's solution:

Stream.of(theArray)

Of the difference between this and Arrays.stream(): it does make a difference if your array is of a primitive type. For instance, if you do:

Arrays.stream(someArray)

where someArray is a long[], it will return a LongStream. Stream.of(), on the other hand, will return a Stream<long[]> with a single element.

19 Comments

@Dima sure, but Arrays.stream() works for that as well
Well, as to streams, convenience! No need to call *Stream.of() when you have Arrays.stream() when dealing with primitive arrays. And as to arrays not being real objects, well, this is Java, this has been the case since 1.0 so deal with it; brooding over this helps nothing
@Dima and so is yours; you consider Arrays.stream() not to be convenient, I consider it to be convenient. Enough said.
@Dima yes, I find your argument that *Stream.of() is more convenient to be fallacious; because it's a matter of preferences. I prefer Arrays.stream() for such cases, which makes it wrong as a general rule that Stream.of() is more convenient (Peano algebra).
@Dima: it's a matter of preference. The differences are so incredibly tiny that it doesn't matter at all. More specifically: a difference of a few characters is nothing. An additional import to a package inside the standard libraries is nothing. And really, manually creating an array instead of a varargs overload is nothing.
|
15
Stream.of("foo", "bar", "baz")

Or, if you are already have an array, you can also do

Stream.of(array) 

For primitive types use IntStream.of or LongStream.of etc.

4 Comments

What I don't understand is, when an int[] can be passed to a method accepting varargs, why won't Stream.of(intArray) produce a Stream<Integer> instead of Stream<int[]>? Also, is there any technical reasoning why there are specialized Stream classes for primitives?
Java primitives are weird beasts. int[] isn't like other arrays. It's not a subclass of Object[], but it is a subclass of Object. So, when you pass it to Stream.of, it's taken as the Object, parameter, and you get a stream of int[]. That is one of the reasons to have specialized classes for primitive - if you didn't creating streams from primitive arrays would be pretty painful. The other reason, is that specialized classes are more efficient, because the do not need to incur the Object overhead from boxing (converting int to Integer to make it look like normal objects).
Ah, since int[] is an Object, it would match the overloaded method of(T t) and hence it returns Stream<int[]>. So, theoretically speaking, if this method were not available, we would have got the Stream<Integer> in return? or maybe it results in a compilation error because it couldn't find the matching method? i.e. int[] can't be treated as T...
No, we'd still not get Stream<Integer> that way, because Stream.of(t ... T) would still match the same way.
1

You can use Arrays.stream :

Arrays.stream(array); 

This ensures the return type of steam based on your array input type if its String [] then return Stream<String>, if int [] then returns IntStream

When you already know input type array then good to use specific one like for input type int[]

 IntStream.of(array); 

This returns Intstream.

In first example, Java uses method overloading to find specific method based on input types while as in second you already know the input type and calling specific method.

Comments

1

rarely seen, but this is the directest way

Stream.Builder<String> builder = Stream.builder();
for( int i = 0; i < array.length; i++ )
  builder.add( array[i] );
Stream<String> stream = builder.build();

Comments

0

You can make it also by low level method which has parallel option:

Update: Use full array.length (not 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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.