What is the easiest/shortest way to convert a Java 8 Stream into an array?
-
3I'd suggest you to revert the rollback as the question was more complete and showed you had tried something.skiwi– skiwi2014-04-15 09:13:21 +00:00Commented Apr 15, 2014 at 9:13
-
2@skiwi Thanks! but i thought the attempted code does not really add more information to the question, and nobody has screamed "show us your attempt" yet =)user972946– user9729462014-04-15 09:20:32 +00:00Commented Apr 15, 2014 at 9:20
-
21@skiwi: Although I usually shout at the do-my-homework-instead-of-me questions, this particular question seems to be clearer to me without any additional mess. Let's keep it tidy.Honza Zidek– Honza Zidek2014-04-16 11:21:24 +00:00Commented Apr 16, 2014 at 11:21
-
1You can find a lot of answers and guidance in the official docs of the package: docs.oracle.com/javase/8/docs/api/java/util/stream/…Christophe Roussy– Christophe Roussy2020-04-01 09:07:27 +00:00Commented Apr 1, 2020 at 9:07
-
To collect the elements of a stream into a thing, use a collector. There are several utility methods in Collectors.PaulMurrayCbr– PaulMurrayCbr2024-05-16 15:48:13 +00:00Commented May 16, 2024 at 15:48
10 Answers
The easiest method is to use the toArray(IntFunction<A[]> generator) method with an array constructor reference. This is suggested in the API documentation for the method.
String[] stringArray = stringStream.toArray(String[]::new);
It finds a method that takes in an integer (the size) as argument, and returns a String[], which is exactly what (one of the overloads of) new String[] does.
You could also write your own IntFunction:
Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);
The purpose of the IntFunction<A[]> generator is to convert an integer, the size of the array, to a new array.
Example code:
Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);
Prints:
a
b
c
9 Comments
toArray(sz -> new String[sz]) so I'm not sure that one can really say what the solution should or must be.sz -> new String[sz] makes a new function where as the constructor reference does not. It depends how much you value Garbage Collection Churn I guess.private method, which cannot cause churn, and both versions need to create a new object. A reference creates an object that points directly at the target method; a lambda creates an object that points at the generated private one. A reference to a constructor should still perform better for lack of indirection and easier VM optimization, but churning has nothing to do with it.If you want to get an array of ints, with values from 1 to 10, from a Stream<Integer>, there is IntStream at your disposal.
Here we create a Stream with a Stream.of method and convert a Stream<Integer> to an IntStream using a mapToInt. Then we can call IntStream's toArray method.
Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10);
//or use this to create our stream
//Stream<Integer> stream = IntStream.rangeClosed(1, 10).boxed();
int[] array = stream.mapToInt(x -> x).toArray();
Here is the same thing, without the Stream<Integer>, using only the IntStream:
int[]array2 = IntStream.rangeClosed(1, 10).toArray();
Comments
You can convert a Java 8 stream to an array using this simple code block:
String[] myNewArray3 = myNewStream.toArray(String[]::new);
But let's explain things more. First, let's create a list of strings filled with three values:
String[] stringList = {"Bachiri", "Taoufiq", "Abderrahman"};
Create a stream from the given Array:
Stream<String> stringStream = Arrays.stream(stringList);
We can now perform some operations on this stream. For example:
Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase());
And finally convert it to a Java 8 Array using these methods:
Classic method (functional interface)
IntFunction<String[]> intFunction = new IntFunction<String[]>() { @Override public String[] apply(int value) { return new String[value]; } }; String[] myNewArray = myNewStream.toArray(intFunction);Lambda expression
String[] myNewArray2 = myNewStream.toArray(value -> new String[value]);Method reference
String[] myNewArray3 = myNewStream.toArray(String[]::new);
Method reference explanation:
It's another way of writing a lambda expression that it's strictly equivalent to the other.
Comments
You can create a custom collector that convert a stream to array.
public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
{
return Collectors.collectingAndThen(
Collectors.toList(),
list ->list.toArray( converter.apply( list.size() ) ) );
}
and a quick use
List<String> input = Arrays.asList( ..... );
String[] result = input.stream().
.collect( CustomCollectors.**toArray**( String[]::new ) );
3 Comments
Collectors.groupingBy so that I could map some attribute to arrays of objects per attribute value. This answer gives me exactly that. Also @DidierL.list -> list.toArray(converter) due to addition of Collection.toArray​(IntFunction)import java.util.List;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
// Create a stream of strings from list of strings
Stream<String> myStreamOfStrings = List.of("lala", "foo", "bar").stream();
// Convert stream to array by using toArray method
String[] myArrayOfStrings = myStreamOfStrings.toArray(String[]::new);
// Print results
for (String string : myArrayOfStrings) {
System.out.println(string);
}
}
}
Try it out online: https://repl.it/@SmaMa/Stream-to-array
2 Comments
Using the toArray(IntFunction<A[]> generator) method is indeed a very elegant and safe way to convert (or more correctly, collect) a Stream into an array of the same type of the Stream.
However, if the returned array's type is not important, simply using the toArray() method is both easier and shorter.
For example:
Stream<Object> args = Stream.of(BigDecimal.ONE, "Two", 3);
System.out.printf("%s, %s, %s!", args.toArray());
Comments
Use:
// Create a stream of string elements
Stream<String> stringStream = Stream.of("A", "B", "C", "D", "E");
// Convert the stream to arrays of strings
String[] stringArray = stringStream.toArray(String[]::new);