java - 为什么 Collectors.groupingBy 会与恒等函数混淆?

标签 java generics java-8

我正在尝试使用来自 Java 8 API 的 Collectors.groupingBy 来计算数组中整数的出现次数,但我遇到了一些奇怪的编译错误。

这是我的代码:

List<Integer> l = Arrays.asList(1, 1, 1, 2, 3, 3, 3, 3);
Map<Integer, Integer> x = l.stream().collect(groupingBy(i -> i, counting()));

遗憾的是,这不会编译,导致以下错误:

error: incompatible types: inferred type does not conform to equality constraint(s)
        Map<Integer, Integer> x = l.stream().collect(groupingBy(i -> i, counting()));
                                                    ^
    inferred: Integer
    equality constraints(s): Integer,Long
1 error

这似乎是一个通用类型问题,因为当我删除通用 Map 类型时,它会编译。这是另一个测试:

List<Integer> l = Arrays.asList(1, 1, 1, 2, 3, 3, 3, 3);
Map x = l.stream().collect(groupingBy(i -> i, counting()));

System.out.println(x);

并且输出符合预期:

{1=3, 2=1, 3=4}

关于如何解决这个问题而不需要在这里和那里转换所有类型的任何想法?

最佳答案

如果你这样做:

Map<Integer, Long> x = l.stream().collect(Collectors.groupingBy(i -> i, Collectors.counting()));

那么你的代码就可以正常编译了。

原因是Collectors.counting()方法定义为:

public static <T> Collector<T, ?, Long> counting()

此处,第三个类型参数表示将在用于计算计数的 BinaryOperator 中使用的类型。

请注意,当您删除 Map 的类型参数时:

Map x = l.stream().collect(groupingBy(i -> i, counting()));

然后该语句成功编译,因为您实际上使用的是 Map 的原始版本,即键和值的类型都是 Object(这是与 LongInteger 和 friend 兼容)。但是,应该避免使用原始类型,因为您可能会在运行时遇到烦人的 ClassCastException(s)。

关于java - 为什么 Collectors.groupingBy 会与恒等函数混淆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31942860/

相关文章:

java - 类是否扩展了另一个的注释?

java - 使用 Quartz 在 Java 中进行异步调度

java - 如果类/接口(interface)具有 val 属性或具有泛型类型的函数,为什么类/接口(interface)不能以 out 作为前缀?

generics - 从和进入实现

java - Java 8 中的质数

Java 8 - 从列表中过滤空字符串不起作用

java - 为什么 Optional.map 使这项任务有效?

java - 使用 ws-security 签署消息时要签署什么

C# 泛型通过反射动态指定类型

java - 如何根据多个标准对多重图进行索引?