Pages

Footer Pages

Spring Boot

Java String API

Java Conversions

Kotlin Programs

Kotlin Conversions

Java Threads Tutorial

Java 8 Tutorial

Wednesday, November 24, 2021

Stream to Array - How To Convert Stream To Array In Java 8?

1. Overview

In this article, we'll explore the different ways to convert Stream to Array in Java 8.

I have shown in the previous article how to convert ArrayList<String> to String[] array in java 8.

Java 8 Stream api provides a method Stream.toArray() method which converts the string to array in a faster way.

Stream.of(String t) method is used to create Stream of Strings as Stream<String>. 

Learn How To Convert Stream To Array In Java 8?


We will be showing the conversion on the following in this article

1.1 Using Method Reference

1.2 Lambda Expression

1.3 Custom class stream to custom class array

1.4 On primitive types

But, for all the cases, you must use the Stream.toArray() method.

Stream.toArray() Syntax:

<A> A[] toArray(IntFunction<A[]> generator);

Let us explore each of these topics. In this article, We are going to show examples of how to convert Stream of String into a String array. But, you can convert any Stream of objects into any typed array.

Below all are possible with the toArray() method.

Example 1: Convert Stream<String> to String[] array

Example 2: Convert Stream<Employee> to Employee[] array

Example 3: Convert Stream<CustomClass> to CustomClass[] array

Example 4: Convert Stream<Integer> to Integer[] wrapper Integer array

Example 5: Convert Stream<Integer> to int[] primitive array


2. Using Method Reference

Method Reference is a broad topic. You can go through this article for an advanced level.

Method ref is indicated with "::" double colon operator introduced in java 8 and used to create an instance for a class.

Let us write a simple method with Method reference.

    public static String[]  convertStreamToArray(Stream<String> stringStream){
        String[] strArray = stringStream.toArray(String[]::new);
        return strArray;
    }
Next, write the code to test this method working fine or not.

Look at the complete program.
import java.util.Arrays;
import java.util.stream.Stream;

public class MethodRefStreamToArray {

    public static void main(String[] args) {

        Stream<String> stringStream = Stream.of("hello", "reader", "welcome", "to", "javaprogramto.com", "blog");

        String[] array1 = convertStreamToArray(stringStream);

        System.out.println("Array 1 : "+ Arrays.toString(array1));

        Stream<String> stringStream2 = Stream.of("seocond", "example", "stream to array");

        String[] array2 = convertStreamToArray(stringStream2);

        System.out.println("Array 2 : "+ Arrays.toString(array2));

    }

    public static String[] convertStreamToArray(Stream<String> stringStream) {

        String[] strArray = stringStream.toArray(String[]::new);

        return strArray;
    }
}
Output:
Array 1 : [hello, reader, welcome, to, javaprogramto.com, blog]
Array 2 : [seocond, example, stream to array]

3. Using Lambda Expression


Another way is to pass the lambda expression to the toArray() method. toArray() method takes IntFunction as an argument and it takes size as input and returns String[] array with size.
import java.util.Arrays;
import java.util.stream.Stream;

public class LambdaStreamToArray {

    public static void main(String[] args) {

        Stream<String> stringStream = Stream.of("hello", "reader", "welcome", "to", "javaprogramto.com", "blog");

        String[] array1 = convertStreamToArrayWithLambda(stringStream);

        System.out.println("Array 1 : "+ Arrays.toString(array1));

        Stream<String> stringStream2 = Stream.of("seocond", "example", "stream to array");

        String[] array2 = convertStreamToArrayWithLambda(stringStream2);

        System.out.println("Array 2 : "+ Arrays.toString(array2));

    }

    public static String[] convertStreamToArrayWithLambda(Stream<String> stringStream) {

        String[] strArray = stringStream.toArray(size -> {
            return new String[size];
        });

        return strArray;
    }
}
This program produces the output as same as the above section.

4. Using Custom Generator Class


toArray() method takes IntFunction as argument and it is a Functional Interface.

Let us create a custom class that implements the IntFunction and implements apply() method.
import java.util.Arrays;
import java.util.function.IntFunction;
import java.util.stream.Stream;

public class CustomIntFunctionStreamToArray {

    public static void main(String[] args) {

        Stream<String> stringStream = Stream.of("hello", "reader", "welcome", "to", "javaprogramto.com", "blog");

        String[] array1 = stringStream.toArray(new CustomIntFunction());

        System.out.println("Array 1 : "+ Arrays.toString(array1));

        Stream<String> stringStream2 = Stream.of("seocond", "example", "stream to array");

        String[] array2 = stringStream2.toArray(new CustomIntFunction());;

        System.out.println("Array 2 : "+ Arrays.toString(array2));

    }

}

class CustomIntFunction implements IntFunction<String[]>{

    @Override
    public String[] apply(int size) {
        return new String[size];
    }
}
Output:
Array 1 : [hello, reader, welcome, to, javaprogramto.com, blog]
Array 2 : [seocond, example, stream to array]

5. Stream to Primitive Or Wrapper Array conversion

Let us convert Stream of Integers into Integer Array.

Wrapper Stream to Wrapper[] Array Example

import java.util.Arrays;
import java.util.stream.Stream;

public class WrapperStreamToArray {

    public static void main(String[] args) {

        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);

        Integer[] array1 = integerStream.toArray(Integer[]::new);

        System.out.println("Integer Array 1 : " + Arrays.toString(array1));

        Stream<Integer> integerStream2 = Stream.of(11, 22, 33, 44, 55);

        Integer[] array2 = integerStream2.toArray(size -> new Integer[size]);

        System.out.println("Integer Array 2 : " + Arrays.toString(array2));

    }
}
Output:
Integer Array 1 : [1, 2, 3, 4, 5, 6, 7]
Integer Array 2 : [11, 22, 33, 44, 55]
If you pass the Integer array size as 0 as below will get the runtime exception.
Integer[] array2 = integerStream2.toArray(size -> new Integer[0]);
Exception:
Exception in thread "main" java.lang.IllegalStateException: Begin size 5 is not equal to fixed size 0
	at java.base/java.util.stream.Nodes$FixedNodeBuilder.begin(Nodes.java:1222)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:483)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:550)
	at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:517)
	at com.javaprogramto.java8.streams.toarray.WrapperStreamToArray.main(WrapperStreamToArray.java:18)

Wrapper Stream to int[] primitive Array Example

Stream api has another method mapToInt() method which returns the int primitive values as IntStream. Next, will need to call the toArray() method to get the int[] array.

Similar to this steam api has built-in support for mapToLong() and mapToDouble() methods. All of these methods come under Stream Intermediate Options which returns Stream output.
import java.util.Arrays;
import java.util.stream.Stream;

public class PrimitiveStreamToArray {

    public static void main(String[] args) {

        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);

        int[] array1 = integerStream.mapToInt(primitiveVlaue -> primitiveVlaue).toArray();

        System.out.println("int[] Array 1 : " + Arrays.toString(array1));

        Stream<Integer> integerStream2 = Stream.of(11, 22, 33, 44, 55);

        int[] array2 = integerStream2.mapToInt( i -> i).toArray();

        System.out.println("int[] Array 2 : " + Arrays.toString(array2));

    }
}

7. Exception

If the stream is already closed then it will throw runtime exception saying IllegarStateException and reason is "stream has already been operated upon or closed".
Array 1 : [hello, reader, welcome, to, javaprogramto.com, blog]Exception in thread "main" 
java.lang.IllegalStateException: stream has already been operated upon or closed
	at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:246)
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:517)
	at com.javaprogramto.java8.streams.toarray.CustomIntFunctionStreamToArray.main(CustomIntFunctionStreamToArray.java:19)

8. Conclusion


In this article, You've seen how to convert Any Stream to an Array in java 8 using toArray(), mapToInt(), and of() methods.

All Examples are shown are on GitHub.


No comments:

Post a Comment

Please do not add any spam links in the comments section.