Saturday, August 3, 2019

Java 8 IntStream.Builder - Methods Examples

1. Introduction


In this tutorial, We'll learn how to use IntStream.Builder Interface in Java 8. This is part of java.util.stream package. We have already covered Java 8 Stream API.

IntStream.Builder follows the builder design pattern to build the IntStream object.

IntStream.Builder is a mutable builder for an IntStream. This creates an integer stream which can be added with the values or elements before invoking the build phase. We will discuss how to create a builder instance and its life cycle step by step in this article. For now, you need not worry about these terms. By the end of this article, you will be confident about this interface.



intstream-builder


In the end, We will write example programs using accept(), add() and build methods.


In the previous tutorial, We have seen how to create an empty IntStream instance using empty() method.

Note: This is designed based on the Builder Design Pattern. The Builder is a design pattern designed to provide a flexible solution to various object creation problems in object-oriented programming.

2. Creating Builder instance


Builder is an inner interface in IntStream interface. So directly, We can not create an object using the new keyword. IntStream has provided with a utility method builder() to create an instance of Builder object as below.

Note: builder() is a static method in IntStream.

// builder object creation.
IntStream.Builder builder = IntStream.builder();

3. Builder Internal code


Builder interface extending IntConsumer interface which as accept() and build() abstract methods.

 public interface Builder extends IntConsumer {

        /**
         * Adds an element to the stream being built.
         *
         * @throws IllegalStateException if the builder has already transitioned
         * to the built state
         */
        @Override
        void accept(int t);

        /**
         * Adds an element to the stream being built.
         *
         * @implSpec
         * The default implementation behaves as if:
         * 
{@code
         *     accept(t)
         *     return this;
         * }
* * @param t the element to add * @return {@code this} builder * @throws IllegalStateException if the builder has already transitioned * to the built state */ default Builder add(int t) { accept(t); return this; } /** * Builds the stream, transitioning this builder to the built state. * An {@code IllegalStateException} is thrown if there are further * attempts to operate on the builder after it has entered the built * state. * * @return the built stream * @throws IllegalStateException if the builder has already transitioned to * the built state */ IntStream build(); }

builder() method internal code:


public static Builder builder() {
        return new Streams.IntStreamBuilderImpl();
    }

4. InstStream.Builder Life Cycle


Builder has a life cycle with two stages.

A) Build Stage
B) Built Stage

The first stage, "Build" is started after creating Builder instance. Once the Builder is ready, Integer values can be added to the builder in Build Stage using add(T value) method. After adding the all the required values then call build() method which will close the first stage and starts the second stage "Built". build() method helps to transition the builder to the built stage. In the "Built" stage values can not be accepted by the builder. An IllegalStateException is thrown if there are further attempts to operate on the builder after it has entered the built state.

5. Methods and Examples


IntStream.Builder has a total of 3 methods such as 1 default and 2 abstract methods.

add(int t): This is a default method and adds an element to the stream being built.

accept(int t): Adds an element to the stream being built.
build(): Builds the stream, transitioning this builder to the built state.

5.1 add(int i) Example


Adds an element to the stream being built. That means the value provided is added to the builder. This method should be called only in the first phase "Build" only.

Syntax:

default IntStream.Builder add(int t)

This is a default method. Accepts int parameter and return the current Builder instance after adding the given value.

Example:

// builder object creation.
IntStream.Builder builder = IntStream.builder();
builder.add(10);
builder.add(30);
builder.add(50);
builder.add(70);
builder.add(90);

System.out.println(builder);

Output:

java.util.stream.Streams$IntStreamBuilderImpl@78308db1

Builder implementation class is IntStreamBuilderImpl.

Builder object creation using builder pattern as below.

IntStream.Builder newBuilder = IntStream.builder().add(0).add(5).add(10).add(15).add(20);
System.out.println(newBuilder);

This is similar to the StringBuffer.append() method.

5.2 IntStream build() Example


This method is used to stop the first phase and enters into the Built Stage. This is mainly for creating or building the IntStream object after adding all the values using the above add() method.

Syntax:

IntStream build()

Example:

package com.java.w3schools.blog.java8.intstream;

import java.util.stream.IntStream;

/**
 * Java 8 IntStream.Builder build() Methods Example
 * 
 * @author venkatesh
 *
 */
public class IntStreamBuilderBuildExample {

 public static void main(String[] args) {

  IntStream.Builder intBuilder = IntStream.builder().add(3).add(6).add(9).add(12).add(15);

  IntStream intStream = intBuilder.build();
  System.out.println("IntStream values generated from Builder");
  intStream.forEach(i -> System.out.println(i));
 }

}


Output:

IntStream values generated from Builder
3
6
9
12
15

5.3 accept(int i) Example


Adds the values to the builder which works similar to the add(int i) method. But this is inherited from IntConsumer Functional Interface.

Syntax:

void accept(int t)

This does not return any value but add() method returns Builder instance. This does not follow builder pattern. accept() and add() methods can be used together as in the below example.

Example:

package com.java.w3schools.blog.java8.intstream;

import java.util.stream.IntStream;

/**
 * Java 8 IntStream.Builder build() Methods Example
 * 
 * @author venkatesh
 *
 */
public class IntStreamBuilderBuildExample {

 public static void main(String[] args) {

  IntStream.Builder intBuilder = IntStream.builder();
  intBuilder.accept(100);
  intBuilder.accept(200);
  intBuilder.accept(300);
  intBuilder.accept(400);
  intBuilder.accept(1500);

  intBuilder.add(222).add(333).add(444);

  IntStream intStream = intBuilder.build();
  System.out.println("IntStream values generated from Builder");
  intStream.forEach(i -> System.out.println(i));
 }

}

Output:

IntStream values generated from Builder
100
200
300
400
1500
222
333
444

6. IllegalStateException


IllegalStateException will be thrown while using all these mehtods (add(), accept() and build()).

Once the build() method is invoked then next to no accept() or add() method operations are not allowed. If we do so then these will throw runtime exception saying IllegalStateException.

See the example program to produce IllegalStateException. Calling accept() method after calling build() method.


package com.java.w3schools.blog.java8.intstream;

import java.util.stream.IntStream;

/**
 * Java 8 IntStream.Builder IllegalStateException Example
 * 
 * @author venkatesh
 *
 */
public class IntStreamBuilderIllegalStateExceptionExample {

 public static void main(String[] args) {

  IntStream.Builder intStreamBuilder = IntStream.builder().add(300);
  IntStream intStream = intStreamBuilder.build();
  System.out.println("Build method is called and builder is closed. Not allowed to perform any operations");

  System.out.println("Trying to add values to builder");
  intStreamBuilder.accept(150);
    
 }
}

Output:

Build method is called and builder is closed. Not allowed to perform any operations
Trying to add values to builder
Exception in thread "main" java.lang.IllegalStateException
 at java.base/java.util.stream.Streams$IntStreamBuilderImpl.accept(Streams.java:461)
 at com.java.w3schools.blog.java8.intstream.IntStreamBuilderIllegalStateExceptionExample.main(IntStreamBuilderIllegalStateExceptionExample.java:20)

Replacing the accept() method call with add() will result in the same exception.

Even if we try to call build() method twice on the same IntStream.Builder object then it will throw the same exception.

IntStream intStream1 = intStreamBuilder.build
IntStream intStream2 = intStreamBuilder.build();

7. Conclusion


In this article, We've covered in-depth on IntStream.Builder. It is built on the Builder Desing Pattern. It has accept(), add() and build() methods. Explained with examples for all methods.

Its life cycle has two phases.

Build phase: Creates the Builder instances and adding the values to the builder using accept() or add() method.
Built phase: It generates the IntStream from Builder object. For this, we must invoke the build() method.

All Builder methods throw IllegalStateException in the following scenarios.

A) Calling add or accept methods after calling build() method
B) Calling build() method twice on the builder object.

All the examples code shown in this article are available over GitHub.
API Ref


No comments:

Post a Comment