提问者:小点点

收集要映射的IntStream时出错


以下代码

String[] values = ...
.... 
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < values.length; i++) {
    map.put("X" + i, values[i]);
}

由IntelliJ转换为:

Map<String, Object> map = IntStream.range(0, values.length)
        .collect(Collectors.toMap(
                i -> "X" + i,
                i -> values[i],
                (a, b) -> b));

可以缩短为

Map<String, Object> map = IntStream.range(0, values.length)
            .collect(Collectors.toMap(
                    i -> "X" + i,
                    i -> values[i]));

这两个流版本不编译。

IntelliJ,暗示值中的i存在问题[i]:

不兼容的类型
必需:int找到:java。lang.对象

编译器抱怨:

错误:(35,17)java:接口java中的方法collect。util。流动IntStream不能应用于给定类型
必需:java。util。作用供应商,爪哇。util。作用ObjIntConsumer,java。util。作用找到了双消费者:java。util。流动收藏家

有人能解释为什么吗?


共1个答案

匿名用户

不太确定intelliJ的建议在那里会有什么效果,它似乎不一致。只要放一个

System.out.print(map);

声明和循环之间的语句,然后它不会建议您进一步替换为collect。

使用IntStream collect时,编译失败,原因是实现collect方法需要三个指定的参数在错误中可见,而

Collectors.toMap(i -> "X" + i, i -> values[i])

只会导致收集器类型的单个参数。

转换表达式的更好方法是

>

  • 要么使用foreach

    Map<String, Object> map;
    IntStream.range(0, values.length).forEach(i -> map.put("X" + i, values[i]));
    

    或者使用box()IntStream转换为Stream

    Map<String, Object> map = IntStream.range(0, values.length).boxed()
               .collect(Collectors.toMap(i -> "X" + i, i -> values[i], (a, b) -> b));
    

    或者正如@Holger所建议的,您可以避免使用forEach和装箱开销,并修改构造以使用IntStream。将三个参数变量收集为:-

    Map<String, Object> map = IntStream.range(0, values.length)
               .collect(HashMap::new, (m,i) -> m.put("X"+i,values[i]), Map::putAll);