Is there any difference between using Stream.builder()
versus creating an ArrayList
and then calling stream()
on it?
Introduced in Java 8, the Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.
There are two types of streams in Java: byte and character. When an I/O stream manages 8-bit bytes of raw binary data, it is called a byte stream. And, when the I/O stream manages 16-bit Unicode characters, it is called a character stream.
Stream builder() returns a builder for a Stream. Syntax : static <T> Stream. Builder<T> builder() where, T is the type of elements.
A mutable builder for a Stream . This allows the creation of a Stream by generating elements individually and adding them to the Builder (without the copying overhead that comes from using an ArrayList as a temporary buffer.)
This post will discuss the difference between Stream.of () and Arrays.stream () method in Java. The Stream.of () and Arrays.stream () are two commonly used methods for creating a sequential stream from a specified array. Both these methods return a Stream<T> when called with a non-primitive type T.
The build () method in Stream.Builder class is used to build the stream. It returns the built stream. The syntax is as follows: Import the following package for the Stream.Builder class in Java: Declare a Stream.Builder: Add some elements in the stream: Now, use the build () method:
The Stream.of () and Arrays.stream () are two commonly used methods for creating a sequential stream from a specified array. Both these methods return a Stream<T> when called with a non-primitive type T. For instance, both Stream.of () and Arrays.stream () returns Stream<Integer> when called on an Integer array.
The Stream of (T… values) returns a sequential ordered stream whose elements are the specified values. Stream.of () method simply calls the Arrays.stream () method for non-primitive types.
This is an implementation detail, but yes, the builder is better optimized to the use case of being incrementally filled, followed by an operation streaming over the contained elements.
In contrast, an ArrayList
has to support arbitrary modification and random access.
So, when repeatedly adding elements to an ArrayList
without specifying a correctly predicted initial capacity, it may need to allocate a new, larger array and copy the current array into it whenever the current capacity is exhausted.
In contrast, the builder has a special support for the single element case, which doesn’t need an array at all. Then, if more elements are added, it will turn to a spined buffer. This buffer starts with a small array like ArrayList
but when its capacity is exhausted, it begins to use an array of arrays instead of repeatedly copying the array to a larger flat array.
So this saves the copying costs you’d have when filling an ArrayList
. You can save these costs for ArrayList
by specifying the right initial capacity, but that only works when an estimate is available. Specifying an initial capacity also removes the optimization for the empty case. So generally, the stream builder can deal with unknown sizes much better.
Another property of this design is that Stream.Builder
can deal with more than 2³¹ elements, unlike ArrayList
, if you have enough memory.
Stream.builder()
is not a terminal operation, so it's lazy. Using the second one, in theory, uses more memory. From the Stream.Builder
Javadoc, This allows the creation of a Stream
by generating elements individually and adding them to the Builder
(without the copying overhead that comes from using an ArrayList
as a temporary buffer.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With