Java流:计算基元数组中的不同值

时间:2019-08-30 14:10:29

标签: java arrays java-8 java-stream primitive

为什么int数组的非重复计数返回的结果与Integer数组的计数不同?在这两种情况下,我都希望结果为3。

int[] numbers1 = { 1, 2, 3 };
System.out.println("numbers1: " + Arrays.toString(numbers1));
System.out.println("distinct numbers1 count: " + Stream.of(numbers1).distinct().count());

Integer[] numbers2 = { 1, 2, 3 };
System.out.println("numbers2: " + Arrays.toString(numbers2));
System.out.println("distinct numbers2 count: " + Stream.of(numbers2).distinct().count());

结果

numbers1: [1, 2, 3]
distinct numbers1 count: 1

numbers2: [1, 2, 3]
distinct numbers2 count: 3

5 个答案:

答案 0 :(得分:6)

在您的第一种情况下,Stream.of(numbers1)的类型为Stream<int[]>,并且其中只有一个值。

在第二种情况下,Stream.of(numbers2)的类型为Stream<Integer>,其中有3个不同的值。

您使用IntStream.of(1, 2, 3)获取原始int的流。

答案 1 :(得分:3)

Streams提供了两个静态Stream<T> of()方法:

public static<T> Stream<T> of(T t) {..}

public static<T> Stream<T> of(T... values) {..}

第一个方法创建一个由单个对象组成的流,该对象作为参数提供,而第二个方法创建一个由数组元素组成的流。
就您而言,int[]参数使of(T values)被调用,而Integer[]参数使of(T... values)被调用。
预期的结果是1,然后是3

为什么编译器没有将两个调用绑定到相同的of()方法?

由于传递的参数的声明类型是对象数组时,编译器会选择最具体的可用方法:of(T... values)
但是,如果传递的参数的声明类型是原始数组,则该方法不匹配:int不是Object。因此,编译器可以选择的其余方法是of(T t)

长话短说:要流式处理原语数组,请不要使用Stream.of(),而应将专用类用于IntStream.of()DoubleStream.of()

答案 2 :(得分:2)

因为在第一个Stream.of方法中,将整个数组视为一个元素-它创建一个带有array元素的流。要使用原始数组,必须使用Arrays.stream

答案 3 :(得分:2)

第一个Stream.of返回一个Stream<int[]>,并且您有1个不同的int[],称为numbers1。第二个Stream.of返回一个Stream<Integer>,您有3个不同的Integers,分别是123。您可以通过以下方式解决此问题:对Stream.of的首次调用将Arrays.stream替换为Stream.of,因为Arrays具有专用的实用程序方法,该方法采用int[]并返回{{ 1}}。

答案 4 :(得分:0)

替换

Stream.of(numbers1)

Arrays.stream(numbers1)

正确地将int[]转换为IntStream以外的Stream<int[]>