【问题标题】:Java Stream Collectors.toList() wont compileJava Stream Collectors.toList() 不会编译
【发布时间】:2017-10-19 10:34:25
【问题描述】:

谁能解释为什么下面的代码不能编译,而第二个却可以?

不要编译

private void doNotCompile() {

    List<Integer> out;
    out = IntStream
            .range(1, 10)
            .filter(e -> e % 2 == 0)
            .map(e -> Integer.valueOf(2 * e))
            .collect(Collectors.toList());

    System.out.println(out);
}

collect 行出现编译错误

  • IntStream 类型中的方法 collect(Supplier, ObjIntConsumer, BiConsumer) 不适用于参数 (Collector>)
  • 类型不匹配:无法从 Collector> 转换为 Supplier

编译

private void compiles() {
    List<Integer> in;

    in = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    List<Integer> out;
    out = in.stream()
            .filter(e -> e % 2 == 0)
            .map(e -> 2 * e)
            .collect(Collectors.toList());

    System.out.println(out);
}

【问题讨论】:

  • 下一次,添加错误消息,而不是仅仅声明它不会编译。

标签: java java-stream collectors


【解决方案1】:

IntStream 没有接受Collectorcollect 方法。如果你想要一个List&lt;Integer&gt;,你必须把IntStream装箱成Stream&lt;Integer&gt;

out = IntStream
        .range(1, 10)
        .filter(e -> e % 2 == 0)
        .map(e -> 2 * e)
        .boxed()
        .collect(Collectors.toList());

.map().boxed() 的替代品是mapToObj()

out = IntStream
        .range(1, 10)
        .filter(e -> e % 2 == 0)
        .mapToObj(e -> 2 * e)
        .collect(Collectors.toList ());

或者你可以使用IntStreamcollect方法:

out = IntStream
        .range(1, 10)
        .filter(e -> e % 2 == 0)
        .map(e -> 2 * e)
        .collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);

【讨论】:

  • "IntStream 没有接受收集器的收集方法" ...特别是因为没有 List&lt;int&gt; 之类的东西
【解决方案2】:

在第一个示例中,您正在对原始整数流进行操作。原始整数不能进入Listbasically because generics in Java are less than ideal。 Java 语言设计者是working on potentially fixing this

同时,要解决这个问题,您需要先将这些原始整数装箱到 Integer wrapper 中。代码示例见Eran's answer

在第二个示例中,您已经在迭代 Integers,所以 It Just Works™。


当我这样做时,我以为我正在将这些 int 装箱为整数 映射器中的 Integer.valueOf

map function of IntStream 接受 IntUnaryOperator,这是一个接受原始 int 并返回原始 int 的功能接口。

您从valueOf 获得的Integer 已拆箱以匹配功能接口。

【讨论】:

  • 谢谢,但当我在映射器中执行 Integer.valueOf 时,我以为我将这些 int 装箱为整数
  • 更新了我的答案:)
  • 我现在明白了,如果我使用 maptoObj 而不是 map,它也可以工作
【解决方案3】:

IntStreamcollect方法在不可编译的情况下是不同的。

public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner)

因此它不接受您提供给collect的参数

您可以通过将 List&lt;Integer&gt; 转换为 IntStream 来解决此问题

【讨论】:

    猜你喜欢
    • 2021-09-06
    • 2022-01-08
    • 1970-01-01
    • 2019-04-19
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    相关资源
    最近更新 更多