6

在我的程序中,我试图使用流打印排序的 int 数组。但是我在使用普通流时得到了错误的输出。并且在使用 int 流时会打印出正确的详细信息。

有关更多详细信息,请参阅下面的核心代码段。

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);

    }


}

我在控制台上得到以下输出:

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

第一行输出是使用不正确的普通 java 流生成的。

为什么我使用普通的 JAVA 流会收到虚假内容?我在这里错过了什么吗?

4

3 回答 3

8

您可以像这样解决您的问题:

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

解释发生了什么:

当您使用Arrays.asList()which 外观时:

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

它采用了类型的可变参数T,在您的情况下,您将它用于int[]对象,因此Arrays.asList()将返回Listint[]不是整数流,因此您必须使用Arrays.stream如下所示的:

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

以获得正确的数据。

于 2019-03-24T07:50:58.990 回答
7

Arrays.asList(arr)返回 a List<int[]>,其唯一元素是arr。因此,流式传输,List然后将该单个元素映射到String.valueOf(x)并收集Collectors.joining(",")将导致 aString其值为该单个数组的toString(),这是您看到的输出。

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"

当您IntStreamint数组创建 an 时,您会获得单个元素(int值)的流,因此您可以将它们装箱,然后转换为Strings 并加入它们以获得所需的输出。

如果你改变,你可以让你的第一个片段工作:

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

到:

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

因为这种方式Arrays.asList(arr)将产生一个List<Integer>包含输入数组的所有元素。

于 2019-03-24T07:51:24.283 回答
0

你可以做得更短一点:

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

结果是0,1,8,10,12,56,78

首先你创建一个IntStream,然后你得到一个Stream<String>收集到最终的String

于 2019-03-24T11:03:02.283 回答