Java 如何为lambda表达式指定类型?

Java 如何为lambda表达式指定类型?,java,generics,java-8,Java,Generics,Java 8,我试过: Stream stream = Pattern.compile(" ").splitAsStream(sc.nextLine()); stream.forEach(item) -> {}); 得到: Compilation Error... File.java uses unchecked or unsafe operations. Recompile with -Xlint:unchecked for details. Compilation Error... 15

我试过:

Stream stream = Pattern.compile(" ").splitAsStream(sc.nextLine());
stream.forEach(item) -> {});
得到:

Compilation Error... 
 File.java uses unchecked or unsafe operations.
 Recompile with -Xlint:unchecked for details.
Compilation Error... 
15: error: incompatible types: incompatible parameter types in lambda expression
            stream.forEach((String item) -> {});
                           ^
 Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
所以我试着:

Stream stream = Pattern.compile(" ").splitAsStream(sc.nextLine());
stream.forEach((String item) -> {});
得到:

Compilation Error... 
 File.java uses unchecked or unsafe operations.
 Recompile with -Xlint:unchecked for details.
Compilation Error... 
15: error: incompatible types: incompatible parameter types in lambda expression
            stream.forEach((String item) -> {});
                           ^
 Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error

我如何才能使这个
.forEach()
通过编译?

您已经将
流定义为一个类型,它删除了所有类型信息,并且(基本上)使用
对象作为类型

试试这个:

Stream<String> stream = Pattern.compile(" ").splitAsStream(sc.nextLine());
//     ^----^ add a generic type to the declaration
stream.forEach(item -> {
    // item is know to be a String
});
或者更简单:

Arrays.stream(sc.nextLine().split(" ")).forEach(item -> {});

虽然更简单,但最后一个版本使用了O(n)空间,因为在执行第一个
forEach()
之前,整个输入被分割。
其他版本使用O(1)空间,因为
模式#splitAsStream()
在内部使用
匹配器来迭代输入,因此一次使用输入匹配。

除非输入非常大,否则这种副作用不会产生太大的影响。

您已经将
流定义为一个类型,它删除了所有类型信息,并且(基本上)使用
对象作为类型

试试这个:

Stream<String> stream = Pattern.compile(" ").splitAsStream(sc.nextLine());
//     ^----^ add a generic type to the declaration
stream.forEach(item -> {
    // item is know to be a String
});
或者更简单:

Arrays.stream(sc.nextLine().split(" ")).forEach(item -> {});

虽然更简单,但最后一个版本使用了O(n)空间,因为在执行第一个
forEach()
之前,整个输入被分割。
其他版本使用O(1)空间,因为
模式#splitAsStream()
在内部使用
匹配器来迭代输入,因此一次使用输入匹配。

除非输入量很大,否则这种副作用不会有多大影响。

非常感谢,为什么内联很重要?在我看来,它只是缩短了代码的行数或字符数,它究竟是如何影响代码的编译的呢???@Jas:如果你正朝着这个方向考虑的话,那么性能就没有任何改进。但是链接所有流操作使得不可能出现像您的问题中那样的声明错误。另外,没有指向流的变量可以确保您不会尝试使用流两次。但是,将其内联修复类型问题的原因是什么?我从未遇到过多行与单行之间存在不同类型问题的情况,但将其内联修复类型问题的原因是什么?为什么将结果分配到
和使用它与使用
内联
版本之间存在差异?为什么它能解决这个问题?@jas
Pattern#splitAsStream()
返回一个
流。如果将其分配给声明为原始(未类型化)
流的
变量,则会丢失键入。当您使用变量
Stream
时,编译器不知道您为其分配了
;编译器只查看声明的类型,而该类型是非类型化的,并且编译时或多或少会将其声明为
Stream
。非常感谢,为什么内联很重要?在我看来,它只是缩短了代码的行数或字符数,它究竟是如何影响代码的编译的呢???@Jas:如果你正朝着这个方向考虑的话,那么性能就没有任何改进。但是链接所有流操作使得不可能出现像您的问题中那样的声明错误。另外,没有指向流的变量可以确保您不会尝试使用流两次。但是,将其内联修复类型问题的原因是什么?我从未遇到过多行与单行之间存在不同类型问题的情况,但将其内联修复类型问题的原因是什么?为什么将结果分配到
和使用它与使用
内联
版本之间存在差异?为什么它能解决这个问题?@jas
Pattern#splitAsStream()
返回一个
流。如果将其分配给声明为原始(未类型化)
流的
变量,则会丢失键入。当您使用变量
Stream
时,编译器不知道您为其分配了
;编译器只查看声明的非类型化类型,编译时或多或少会将其声明为
Stream