为什么mapToInt不能与collect(toList())一起使用?

Cod*_*Man 10 java java-8 java-stream

我写了这段代码:

import java.util.*;
import java.util.stream.Collectors;

public class Main {

    public static void main(String... args) {
        List<String> a = Arrays.asList("One", "Two", "three");
        List<Integer> lengths = a.stream().mapToInt(String::length).collect(Collectors.toList());

    }
}
Run Code Online (Sandbox Code Playgroud)

但它不想编译,说:

Error:(8, 68) java: method collect in interface java.util.stream.IntStream cannot be applied to given types;
  required: java.util.function.Supplier<R>,java.util.function.ObjIntConsumer<R>,java.util.function.BiConsumer<R,R>
  found: java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.List<java.lang.Object>>
  reason: cannot infer type-variable(s) R
    (actual and formal argument lists differ in length)
Run Code Online (Sandbox Code Playgroud)

这里发生了什么事?为什么有限制?如果你使用地图.它没有mapToInt,而是工作正常.

Era*_*ran 11

mapToInt生成一个IntStream没有collect采用单个Collector参数的方法.

由于最终结果是a List<Integer>,您不必将其转换StreamIntStream:

List<Integer> lengths = a.stream().map(String::length).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

如果要将原始数组的元素收集到原始数组中,则将其转换Stream为a IntStream是有意义的Stream:

int[] lengths = a.stream().mapToInt(String::length).toArray();
Run Code Online (Sandbox Code Playgroud)

如果要转换为IntStream仍然使用该collect方法,可以编写以下内容(不太推荐):

List<Integer> lengths = 
    a.stream()
     .mapToInt(String::length)
     .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
Run Code Online (Sandbox Code Playgroud)

  • 简单的方法`a.stream().mapToInt(String :: length).boxed().collect(Collectors.toList());` (3认同)
  • @HadiJ 比只将 `mapToInt` 更改为 `map` 而不必调用 `boxed()` 更简单吗? (2认同)
  • @HadiJ我刚刚演示了如何在`IntStream`上使用`collect`.如果你调用`boxed()`,你不再使用`IntStream`,所以你也可能不会首先映射到`IntStream`,正如我在答案开头所提到的那样. (2认同)

小智 7

有一个简单的方法可以将 IntStream 转换为 Stream。添加boxed()为中间操作,您将能够用作collect()终端操作。

List<Integer> lengths = a.stream().mapToInt(String::length).boxed().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)