Gunjan Shah
Gunjan Shah

Reputation: 5168

Collecting value of int array using normal JAVA Stream

In my program, I am trying to print sorted int array using stream. But I am getting false output while using normal stream. And correct details are getting printed while using int stream.

Please refer below core snippet for more details.

package com.test.sort.bubblesort;

import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class BubbleSortWithRecursion {

    public static void bubbleSort(int[] arr, int n) {

        if (n < 2) {
            return;
        }

        int prevValue;
        int nextValue;
        for (int index = 0; index < n-1; index++) {
            prevValue = arr[index];
            nextValue = arr[index+1];

            if  (prevValue > nextValue) {
                arr[index] = nextValue;
                arr[index+1] = prevValue;
            }
        }

        bubbleSort(arr, n-1);
    }

    public static void main(String[] args) {
        int arr[] = new int[] {10,1,56,8,78,0,12};
        bubbleSort(arr, arr.length);

        **//False Output** :  [I@776ec8df
        String output = Arrays.asList(arr)
            .stream()
            .map(x -> String.valueOf(x))
            .collect(Collectors.joining(","));

        System.out.println(output);

        //Correct Output : 0,1,8,10,12,56,78
        String output2 = IntStream
            .of(arr)
            .boxed()
            .map(x -> Integer.toString(x))
            .collect(Collectors.joining(","));

        System.out.println(output2);

    }


}

And I am getting following output on console :

[I@776ec8df
0,1,8,10,12,56,78

The fist line of output was generated using normal java stream which is not correct.

Why am I getting false content using normal JAVA stream ? Am I missing something here ?

Upvotes: 6

Views: 8393

Answers (3)

Samuel Philipp
Samuel Philipp

Reputation: 11050

You can do it even a bit shorter:

String output = Arrays.stream(arr)
        .mapToObj(String::valueOf)
        .collect(Collectors.joining(","));

The result is 0,1,8,10,12,56,78

First you create an IntStream, then you get a Stream<String> which is collected to the final String.

Upvotes: 0

Eran
Eran

Reputation: 394156

Arrays.asList(arr) returns a List<int[]> whose only element is arr. Therefore streaming that List and then mapping that single element to String.valueOf(x) and collecting with Collectors.joining(",") will result in a String whose value is that single array's toString(), which is the output you see.

String output = Arrays.asList(arr) // List<int[]>
    .stream() // Stream<int[]>
    .map(x -> String.valueOf(x)) // Stream<String> having a single element - "[I@776ec8df"
    .collect(Collectors.joining(",")); // "[I@776ec8df"

When you create an IntStream from the int array, you get a stream of the individual elements (the int values), so you can box them, convert then to Strings and join them to get the desired output.

You can make your first snippet work if you change:

int arr[] = new int[] {10,1,56,8,78,0,12};

to:

Integer arr[] = new Integer[] {10,1,56,8,78,0,12};

since this way Arrays.asList(arr) will produce a List<Integer> containing all the elements of the input array.

Upvotes: 7

Youcef LAIDANI
Youcef LAIDANI

Reputation: 60046

You can solve your issue like so :

String output = Arrays.stream(arr)
        .boxed()
        .map(String::valueOf)
        .collect(Collectors.joining(",")); // 0,1,8,10,12,56,78

Explain what happen :

when you use Arrays.asList() which look :

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

it took varargs of type T, in your case you use it for int[] Object, so Arrays.asList() will return List of int[] and not a stream of ints, so instead you have to use Arrays.stream which look like this :

public static IntStream stream(int[] array) {
    return stream(array, 0, array.length);
}

to get the correct data.

Upvotes: 10

Related Questions