Collectors.toMap无法编译

Eug*_* To 7 java java-stream

此代码无法编译

List<String> pairs = new ArrayList<>();
System.out.println(pairs.stream().collect(Collectors.toMap(x -> x.split("=")[0], x -> x.split("=")[1])));
Run Code Online (Sandbox Code Playgroud)

编译错误是:方法split(String)未定义为System.out.println中的Object错误类型(pairs.stream().collect(Collectors.toMap(x - > x.split("=")[0] ,x - > x.split("=")[1])));

但这个编译很好

List<String> pairs = new ArrayList<>();
Map<String,String> map = pairs.stream().collect(Collectors.toMap(x -> x.split("=")[0], x -> x.split("=")[1]));
System.out.println(map);
Run Code Online (Sandbox Code Playgroud)

有人可以解释原因吗?

更多信息

这是intellij 12; jdk1.8.0_11; 窗户64

See*_*ose 5

我假设您使用的是 IDE(如 Eclipse)。例如,Eclipse 使用自己的编译器并且不使用“javac”命令(来自 JDK)。

所以,我可以重现您的问题,但只能使用 Eclipse。只需使用“javac”在命令行上编译此代码就可以了。

这个问题很简单:Eclipse编译器无法推断出类型Stringcollect方法的参数。所以它只是推断Object(因为这是类型,编译器可以安全地假设)。并且Object不知道split方法。

您可以String通过在 lambda 中显式声明类型来强制编译器知道:

List<String> pairs = new ArrayList<>();
System.out.println(pairs.stream().collect(Collectors.toMap((String x) -> x.split("=")[0], x -> x.split("=")[1])));
Run Code Online (Sandbox Code Playgroud)

...或者通过明确声明geneirctoMap方法的正确类型:

List<String> pairs = new ArrayList<>();
System.out.println(pairs.stream().collect(Collectors.<String, String, String> toMap(x -> x.split("=")[0], x -> x.split("=")[1])));
Run Code Online (Sandbox Code Playgroud)


卢声远*_* Lu 1

IntelliJ 的版本有所不同(只是 IDE 中源代码编辑器中的红线)。代码应该能够被 JDK 成功编译。

IntelliJ 13 适合您的代码。IntelliJ 12 对 lambda 表达式的支持很差。在使用 lambda 表达式时,我在两个版本的 IntelliJ 之间也遇到了类似的问题。