首页 文章

收集IntStream进行映射时出错

提问于
浏览
6

以下代码

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

2个流版本无法编译 .

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

不兼容的类型 . 必需:int Found:java.lang.Object

编译器抱怨:

错误:(35,17)java:接口java.util.stream.IntStream中的方法collect不能应用于给定的类型; required:java.util.function.Supplier,java.util.function.ObjIntConsumer,java.util.function.BiConsumer found:java.util.stream.Collector> reason:无法推断类型变量R(实际和正式)参数列表长度不同)

有谁能解释为什么?

1 回答

  • 3

    关于smartJ的建议如何在那里工作不太确定,似乎不一致 . 刚放一个

    System.out.print(map);
    

    声明和循环之间的声明,然后它不会建议你替换任何进一步收集 .


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

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

    只会导致类型为 Collector 的单个参数 .


    转换表达式的更好方法是

    • 使用 forEach
    Map<String, Object> map;
    IntStream.range(0, values.length).forEach(i -> map.put("X" + i, values[i]));
    
    • 或使用boxed()IntStream 转换为 Stream<Integer> 为: -
    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.collect 三arg变体: -
    Map<String, Object> map = IntStream.range(0, values.length)
               .collect(HashMap::new, (m,i) -> m.put("X"+i,values[i]), Map::putAll);
    

相关问题