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

2022-09-01 20:51:49

我写了这个代码:

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

    }
}

但它不想编译,说:

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)

这是怎么回事?为什么有限制?如果您使用地图。而不是 mapToInt,它工作正常。


答案 1

mapToInt生成一个 ,它没有采用单个参数的方法。IntStreamcollectCollector

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

List<Integer> lengths = a.stream().map(String::length).collect(Collectors.toList());

如果要将 的元素收集到基元数组,则将 转换为 是有意义的:StreamIntStreamStream

int[] lengths = a.stream().mapToInt(String::length).toArray();

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

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

答案 2

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

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

推荐