我一直只使用Java 6,现在正在学习Java 8中的新内容。
上面写着:
Java在java.util.function包中定义了几个通用函数接口。其中一个接口BiFunction描述参数类型T和U以及返回类型R的函数。您可以将字符串比较lambda保存在该类型的变量中:
BiFunction<String, String, Integer> comp
= (first, second) -> Integer.compare(first.length(), second.length()); 但是,这并不能帮助您进行排序。没有任何Arrays.sort方法需要BiFunction。如果您以前使用过函数式编程语言,您可能会觉得这很奇怪。但是对于Java程序员来说,这是非常自然的。接口(例如比较器)有特定的用途,而不仅仅是具有给定参数和返回类型的方法。Java 8保留了这种风格。当您想要使用lambda表达式做一些事情时,您仍然希望记住表达式的目的,并为它创建一个特定的函数接口。
然而,当我看到这个线程:如何将lambda分配给Java 8中的变量?
这个问题的答案建议你去做你不能做的事情。
那么,文章中的信息是不正确的,还是我在这里误读了什么?
谢谢!
发布于 2015-02-05 07:25:56
我在链接中没有看到任何东西,所以答案与文章相矛盾。
类型系统的规则适用于函数接口。
如果将变量声明为BiFunction<String,String,Integer> bifunc,则不允许将其传递给需要Comparator<String>的方法,因为BiFunction<String,String,Integer>不是的子类型 of Comparator<String>。
函数类型遵循所有通常的规则这一事实使得这个新功能能够在最小的扰动下被添加。
如果您希望从一个Comparator中生成一个BiFunction,那么您所要做的就是像这样添加::apply:
BiFunction<String,String,Integer> bifunc = (a,b) ->
Integer.compare(a.length(), b.length());
Arrays.sort(array, bifunc::apply); 发布于 2015-02-05 05:55:52
从这个意义上说,这篇文章是正确的,不能根据BiFunction类型的对象进行排序,但是您总是可以使用Comparator。但是,嘿,他们都可以有相同的身体。例如:
private static void sort(Comparator<String> ls){
Arrays.sort(someArray, ls);
}
Comparator<String> comp = (String f1, String f2) -> Integer.compare(f1.length(), f2.length());
sort(comp);
BiFunction<String, String, Integer> func = (String f1, String f2) -> Integer.compare(f1.length(), f2.length());
sort((String f1, String f2) -> Integer.compare(f1.length(), f2.length())); //line-4
sort(func) // compiler error在上面的第4行,您可以传递一个与func完全相同的lambda。但是仍然不能将func传递给sort。java8中的Lambdas是一些FunctionalInterface的实现。函数接口根据其引用类型得到它们的类型。这就是初始化时相同的lambda可以是BiFunction还是Comparator的原因。
但是一旦一个lambda被构造并且它得到了它的类型,那么你就不能改变它。因此,不能将类型为func的BiFunction传递给期望Comparator的排序。
发布于 2015-02-05 08:02:57
这篇文章是正确的。您不能将例如BiFunction分配给Comparator。
尽管如此,这个由Brian编写的伟大的文章以一种很好的方式解释了这个问题。
当编译器遇到lambda表达式时,它首先将lambda体降为与lambda表达式的参数列表和返回类型匹配的方法。
因此,一只羔羊可以被去除--但这意味着什么呢?基本上,它意味着创建一个与lamdba相匹配的新方法(可能)。
class A {
public void foo() {
List<String> list = ...
list.forEach( s -> { System.out.println(s); } );
}
}上面的代码将被描述为如下所示:
class A {
public void foo() {
List<String> list = ...
list.forEach( [lambda for lambda$1 as Consumer] );
}
static void lambda$1(String s) {
System.out.println(s);
}
}所以,在BiFunction和Comparator的例子中。所提供的lambda可分配给以下两个方面:
// Assign the lambda to a BiFunction
BiFunction<String, String, Integer> b1 =
(first, second) -> Integer.compare(first.length(), second.length());
// Assign the lambda to a Comparator
Comparator<String> c1 =
(first, second) -> Integer.compare(first.length(), second.length());
// But, once the lambda has been assigned to a type you can not reassign it
BiFunction<String, String, Integer> b2 = c1; // <-- Error注意,一旦将lambda分配给了类型(BiFunction或Comparator),那么就不能重新分配它,即使lambda表达式匹配。
https://stackoverflow.com/questions/28336350
复制相似问题