The Stream.Builder interface

The Stream.Builder<T> builder() static method returns an internal (located inside the interface Stream interface) Builder interface that can be used to construct a Stream object. The Builder interface extends the Consumer interface, and has the following methods:

Using the add() method is straightforward:

Stream.<String>builder().add("cat").add(" dog").add(" bear")
.build().forEach(System.out::print); //prints: cat dog bear

Just notice the <String> generics that we have added in front of the builder() method. This way, we tell the builder that the stream we are creating will have String type elements. Otherwise, it will add them as Object types.

The accept() method is used when the builder is passed as a parameter of the Consumer type, or when you do not need to chain the methods that add the elements. For example, here is how the builder is passed in as a Consumer object:

Stream.Builder<String> builder = Stream.builder();
List.of("1", "2", "3").stream().forEach(builder);
builder.build().forEach(System.out::print); //prints: 123

There are also cases where there is no need to chain the methods while adding the stream elements. The following method receives a list of String objects, and adds some of them (those that contain the character a) to a stream:

Stream<String> buildStream(List<String> values){
Stream.Builder<String> builder = Stream.builder();
for(String s: values){
if(s.contains("a")){
builder.accept(s);
}
}
return builder.build();
}

Notice that we have added the <String> generics the Stream.Builder interface for the same reason—to tell the builder that the elements we are adding should be treated as String types.

When the preceding method is called, it produces the expected result:

List<String> list = List.of("cat", " dog", " bear");
buildStream(list).forEach(System.out::print); //prints: cat bear