假设我们有一个Iterator<Integer> iterator.因为Iterable是一个功能界面,我们可以写:
Iterable<Integer> iterable = () -> iterator;
Run Code Online (Sandbox Code Playgroud)
那么我们当然可以iterable用作增强的for循环表达式:
for (Integer i : iterable) foo(i);
Run Code Online (Sandbox Code Playgroud)
那么为什么呢
for (Integer i : () -> iterator) foo(i);
Run Code Online (Sandbox Code Playgroud)
不允许?(导致以下编译器错误:)
error: lambda expression not expected here
for (Integer i : () -> iterator) foo(i);
^
Run Code Online (Sandbox Code Playgroud)
使目标类型显式为
for (Integer i : (Iterable<Integer>) () -> iterator) foo(i);
Run Code Online (Sandbox Code Playgroud)
显然有效,但为什么编译器不能推断出λ-expression的目标类型?从表达式是λ表示法的事实来看,编译器不应该清楚目标类型不能是一个Array,因此必须是Iterable?
这只是语言设计师的疏忽,还是我还缺少其他的东西?
我想知道方法引用和功能接口的所有这些东西如何在较低级别上工作.最简单的例子是我们有一些List
List<String> list = new ArrayList<>();
list.add("b");
list.add("a");
list.add("c"):
Run Code Online (Sandbox Code Playgroud)
现在我们想用Collections类对它进行排序,所以我们可以调用:
Collections.sort(list, String::compareToIgnoreCase);
Run Code Online (Sandbox Code Playgroud)
但是,如果我们定义自定义比较器,它可能是这样的:
Comparator<String> customComp = new MyCustomOrderComparator<>();
Collections.sort(list, customComp::compare);
Run Code Online (Sandbox Code Playgroud)
问题是Collections.sort有两个参数:List和Comparator.由于Comparator是功能接口,因此可以使用具有相同签名(参数和返回类型)的lambda表达式或方法引用替换它.那么它是如何工作的,我们也可以传递compareTo只引用一个参数并且这些方法的签名不匹配?如何在Java8中翻译方法引用?
当Java方法接受a时Function<? super T, ? extends U>,可以使用如下语法提供方法引用:MyClass::myMethod.
但是,我想知道是否有一种链接多个方法调用的方法.这是一个说明案例的例子.
// on a specific object, without lambda
myString.trim().toUpperCase()
Run Code Online (Sandbox Code Playgroud)
我想知道是否有语法将其转换为lambda表达式.我希望有类似的东西:
// something like: (which doesn't work)
String::trim::toUpperCase
Run Code Online (Sandbox Code Playgroud)
或者,是否有一个实用程序类来合并函数?
// example: (which does not exist)
FunctionUtil.chain(String::trim, String::toUpperCase);
Run Code Online (Sandbox Code Playgroud)