因此,我的函数式程序员喜欢像python这样的语言,将函数视为一等公民。看起来Java 8已经屈服于压力和#34;"实现了lambda表达式和方法引用之类的东西。
我的问题是,Java是否正在使用第一类函数,或者这实际上只是语法糖来减少实现匿名类/接口(如runnable)所需的代码量? (我的直觉说后者)。
我的理想情景
Map<String,DoubleToDoubleFunc> mymap = new HashMap<String,DoubleToDoubleFunc>();
...
mymap.put("Func 1", (double a, double b) -> a + b);
mymap.put("Func 2", Math::pow);
...
w = mymap.get("Func 1")(y,z);
x = mymap.get("Func 2")(y,z);
答案 0 :(得分:4)
没有function structural type in Java 8。但Java始终拥有一流的对象。事实上,它们已被用作替代品。从历史上看,由于缺少一流函数,我们到目前为止所做的是将函数包装在一个对象中。这些是着名的SAM类型(单一抽象方法类型)。
所以,而不是
function run() {}
Thread t = new Thread(run);
我们
Runnable run = new Runnable(){ public void run(){} };
Thread t = new Thread(run);
也就是说,我们将函数放在一个对象中,以便能够将它作为值传递。因此,一流的对象长期以来一直是替代解决方案。
JDK 8简化了这个概念的实现,他们称之为这种类型的包装器接口和功能接口&#34;并提供一些语法糖来实现包装器对象。
Runnable run = () -> {};
Thread t = new Thread(run);
但最终,我们仍在使用一流的对象。它们具有与一流功能类似的特性。它们封装了行为,它们可以作为参数传递并作为值返回。
在lambda mailing list Brian Goetz对推动这种设计的一些原因作了很好的解释。
按照我们今天讨论的方式,这里有一个方面 我们在哪里前进。我们探索了&#34;也许是lambdas的道路 只是内部类实例,这将非常简单&#34;,但是 最终来到了&#34;职能是一个更好的方向 为了语言的未来&#34;。
这种探索分阶段进行:首先在EG之前进行 成立,然后当EG讨论问题时再次成立。该 以下是我对这个问题的立场。希望,这填补了一些 目前的规范和我们所说的内容之间的差距 关于它。
关于lambdas是对象还是对象的问题 并不是很大程度上归结为哲学问题,例如&#34;什么是 lambdas真的&#34;,&#34;为什么Java会受益于lambdas&#34;,最终 &#34;如何最好地发展Java语言和平台。&#34;
甲骨文的立场是Java必须发展 - 当然要小心 - 为了保持竞争力。当然,这很困难 平衡行为。我相信,发展Java的最佳方向是 鼓励更具功能性的编程风格。 Lambda的作用 主要是为了支持更多的发展和消费 功能类库;我提供了诸如此类的例子 filter-map-reduce来说明这个方向。
生态系统中有大量证据支持这一假设 如果给予工具这么容易,面向对象的程序员 准备接受功能性技术(如不变性)和 将它们用于面向对象的世界观,并将写作 因此,更好,更不容易出错的代码。简单地说,我们相信 我们可以为Java开发人员做的最好的事情是给他们一个温和的推动 更具功能性的编程风格。我们不会去 把Java变成Haskell,甚至变成Scala。但方向是 清楚。
Lambda是这次演变的首期付款,但它远非如此 故事的结局。故事的其余部分尚未撰写,但是 保留我们的选择是我们评估方法的一个关键方面 我们在这里做出的决定。
这就是为什么我一直坚持认为lambda不是 对象。我相信&#34; lambdas只是对象&#34;位置,而 非常舒适和诱人,猛烈砸门 语言演变的潜在有用方向。
作为一个例子,让我们看一下函数类型。 lambda strawman devoxx提供了函数类型。我坚持要把它们删掉,然后 这让我不受欢迎。但我对函数类型的反对并非如此 我不喜欢功能类型 - 我喜欢功能类型 - 但是那样 函数类型与Java类型的现有方面严重冲突 系统,擦除。删除的功能类型是两个世界中最糟糕的。 所以我们从设计中删除了它。
但我不愿意说#34; Java永远不会有功能类型&#34; (虽然我认识到Java可能永远不会有函数类型。)I 相信为了获得功能类型,我们必须先处理 擦除。这可能是,也可能是不可能的。但在一个世界 具体的结构类型,功能类型开始做更多 感。
世界的lambdas-are-objects视图与此可能发生冲突 未来。 lambdas-are-functions对世界的看法并没有 保持这种灵活性是支持不这样做的一个要点 即使是对象的外观,也会给lambda带来负担。
您可能认为当前的设计与对象紧密相关 lambdas的框 - SAM类型 - 使它们成为有效的对象 无论如何。但是这已经被小心地从表面区域隐藏起来了 为了让我们能够考虑“赤身裸体”。 lambda在将来,或考虑 lambdas的其他转换上下文,或者更多地集成lambdas 紧紧地控制构造。我们现在不这样做,而且我们 甚至没有这样做的具体计划,但能够做到 未来可能会这样做是设计的关键部分。
我对Java的未来感到乐观,但我们有时会继续前进 不得不放弃一些舒适的想法。 Lambdas-are-functions打开 门。 Lambdas-are-objects关闭它们。我们更愿意看到那些门 离开了。
答案 1 :(得分:2)
他们并非真正的IMO一流功能。 Lambda最终是功能接口的一个实例。但它确实为您提供了一流功能的优势。您可以将它作为参数传递给需要功能接口实例的方法。您可以将其分配给变量,在这种情况下,将使用目标类型推断其类型。您可以从方法中返回它,等等。
此外,lambdas并不能完全取代匿名类。并非所有匿名类都可以转换为lambda。你可以通过this answer获得关于两者之间差异的一个很好的解释。所以,没有lambdas不是匿名类的语法糖。
答案 2 :(得分:1)
匿名课程不是语法糖;它编写的内容有点涉及。 (并不是说这样做是错误的; 任何语言都有自己的实现细节,如何编译lambdas,而Java并不比其他许多语言差。)
请参阅http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html了解完整的细节。
答案 3 :(得分:1)
interface DoubleDoubleToDoubleFunc {
double f(double x, double y);
}
public static void main(String[] args) {
Map<String, DoubleDoubleToDoubleFunc> mymap = new HashMap<>();
mymap.put("Func 1", (double a, double b) -> a + b);
mymap.put("Func 2", Math::pow);
double y = 2.0;
double z = 3.0;
double w = mymap.get("Func 1").f(y,z);
double v = mymap.get("Func 2").f(y,z);
}
所以它仍然是语法糖,只是在某种程度上。