How to convert Java 8 Stream to Array or ArrayList - Example Tutorial

It's relatively easy to convert a Stream to an array in Java 8 by using the toArray() method of java.util.Stream class. By using this method you can convert any type of Stream to a corresponding array e.g. a Stream of Strings can be converted into an array of String, or a Stream of integers can be converted into an array of Integers. The Stream.toArray() method is also overloaded, the one which doesn't take any parameter returns an Object[] which might not be very useful, particularly if you want to convert Stream of T to array of T. On the other hand, the overloaded version of toArray(IntFunction[] generator) returns an array containing the elements of this stream, using the provided generator function to allocate the returned array, as well as any additional arrays that might be required for a partitioned execution or for resizing.

This toArray() method accepts a function which produces a new array of the desired type. The generator function takes an integer, which is the size of the desired array and produces an array of the desired size.

If you are familiar with method reference then this can be expressed even more concisely with an array constructor reference. You can pass this method a lambda expression or use the array reference to further shorten it as shown by a couple of examples in this article.




Stream to Array using lambda expression in Java 8

Here is the simplest way to convert a Stream of objects into an array of Objects. Suppose, the library object is a list of books and we need to convert that into an array.

Of course, you can directly convert a list to an array without going via Stream as shown here, but for the purpose of this example, we'll use Stream to perform that conversion.

Another reason to use Stream is filtering and lazy evaluation, for example, if you just want fiction books from a list of books, if you directly convert a list to an array, then you won't be able to filter it, but by using Stream you can just use the filter() method for lazy filtering.

Once you got the stream with the interesting value, just call the toArray() method and passing them a generator function which will be used to convert each element of Stream to the corresponding object as shown in the following example:

Book[] books = library.stream()
                      .filter(b -> p.getTopic() == FICTION)
                      .toArray(size -> new Integer[size]);  

Now, the books array contains all books from the list library where the topic is FICTION. You can see that we pass the generator function using a lambda expression.




Stream to array using method reference

Now, you can make the above example, even more, shorter by using the method reference in form of a constructor reference. This will eliminate the lambda expression we have passed in above example:

Book[] books = library.stream()
                      .filter(b -> p.getTopic() == FICTION)
                      .toArray(Book[]::new);   

You can see that this example is even more elegant, classic, and easy to understand than the previous example. If you are not very familiar with method reference and constructor reference then I suggest you reading a good book on Java 8 which is focused on stream and lambda expression e.g. Java 8 in Action by Raoul-Gabriel Urma, Mario Fusco, and Alan Mycroft.

How to convert Java 8 Stream to Array or ArrayList with example


Stream to ArrayList in Java 8

Now, you have seen how to convert a Java 8 Stream to the array, you can use all the techniques you already know to convert an array to ArrayList to get an ArrayList, but what is the fun if you still have to do it in the old Java way? So, let's find out the new way to convert Java 8 Stream to ArrayList.

If you recall our previous examples e.g. converting a Stream to List and converting Stream to Map, then you know that you can use the collect() method to accumulate stream elements in the choice of your collection.

You can use the utility class Collectors and it's conversion methods like toList() and toMap() to get the List and Map from a Stream in Java 8.

This is fine, but in order to get ArrayList from Stream, you just need to know a little bit more. You need to know that Collectors.toList() method can return any type of list, as it doesn't provide any guarantee on the type, thread-safety, or immutability of returned List.

Though, there is a similar method called toCollection() which accepts a supplier, which can be used to convert Stream to ArrayList. All you need to do is provide the ArrayList::new as supplier and toCollection() method will wrap all elements of a stream in an ArrayList and return its reference to you.  You can read Java SE 8 for the Really Impatient to learn more about this behavior of Collector.

Java 8 Stream to Array or ArrayList program example


Now, let's see a real-life example of how to convert Java 8 Stream to ArrayList in Java.

ArrayList<Book> listOfBooks = library.stream()
                                     .filter(b -> p.getTopic() == BIOGRAPHY
                                     .toCollection(ArrayList::new);      

You can see that by using the Collectors or toCollection() method it's extremely easy to convert a Stream of values into an ArrayList of objects.

Here is also a Java program to demonstrate various ways to convert a Stream to Array and ArrayList in Java 8:

How to convert Java 8 Stream to Array or ArrayList


That's all about how to convert a Java 8 Stream to Array and ArrayList in Java. It's not that difficult, you just need to know the right methods from Stream API to do the conversion. Use the Stream.toArray(IntFunction) method when you want a typed array from Stream e.g. an Integer array from a stream of Integer objects or a String array from a stream of Strings. Alternatively you can use toArray() method to get an Object[].


Further Learning
Java Fundamentals: Collections
From Collections to Streams in Java 8 Using Lambda Expressions
The Ultimate Java 8 Tutorial

Other Java 8 tutorial and articles you may like to explore

P.S - In order to convert Stream to ArrayList, you can use toCollection() method by passing ArrayList constructor reference. Don't use the toList() method because it doesn't specify which type of List it will return. See Java SE 8 for Really Impatient to learn more about Stream and interoperability with Java Collection framework.

No comments:

Post a Comment