Java 8 函数式:中途丢失类型信息

S1l*_*0rm 5 java lambda functional-programming

考虑这个转换示例(请参阅有关此处应发生的情况的详细说明):

Map<String, Integer> transform(Map<Integer, List<String>> old) {
    old.entrySet().stream()
       .flatMap(entry -> entry.getValue().stream()
                   .map(letter -> letter.toLowerCase())
                   .map(lowerCaseLetter -> new SimpleEntry<String, Integer>(lowerCaseLetter, entry.getKey())))
       // at this point, the type is Stream<Object>, not Stream<SimpleEntry<String,Integer>>
       .collect(Collectors.toMap());

  }
Run Code Online (Sandbox Code Playgroud)

为什么关于特定类型的信息在这里丢失了,我该如何解决这个问题?

Ale*_* C. 2

Eclipse 自身的编译器(尤其是类型推断)和 Java 8 功能仍然存在问题。在这种情况下,当您遇到此类问题时,请先尝试使用 javac 进行编译。如果它能编译,那么肯定是 Eclipse 的问题。

如果您需要坚持使用 Eclipse,您也许可以通过提供类型参数来帮助 ECJ(Eclipse 的编译器),但通常您不应该这样做(在早期版本中可能是这样,但 java 编译器在类型推断方面做出了巨大的改进) 。

您可以向 Eclipse 开发团队填写错误(之​​前检查您是否拥有最新版本),但 java 8 的错误跟踪器非常密集。

一种替代方案是切换到使用 javac 的 IntelliJ,这是我在 Java 8 之后切换到它的主要原因之一......

查看您的代码,您可以使其稍微短一些:

Map<String, Integer> transform(Map<Integer, List<String>> old) {
    return old.entrySet().stream()
              .flatMap(e -> e.getValue().stream().map(s -> new SimpleEntry<>(s.toLowerCase(), e.getKey())))
              .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue));
}
Run Code Online (Sandbox Code Playgroud)