Java 8 lambda 表达式和一等值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15221659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:53:54  来源:igfitidea点击:

Java 8 lambda expression and first-class values

javalambdajava-8

提问by xdevel2000

Are Java 8 closures really first-class values or are they only a syntactic sugar?

Java 8 闭包真的是一流的值还是只是一种语法糖?

回答by Stuart Marks

I would say that Java 8 closures ("Lambdas") are neither mere syntactic sugar nor are they first-class values.

我想说的是 Java 8 闭包(“Lambdas”)不仅是语法糖,也不是一流的值。

I've addressed the issue of syntactic sugar in an answerto another StackExchange question.

我已经在另一个 StackExchange 问题的回答中解决了语法糖的问题。

As for whether lambdas are "first class" it really depends on your definition, but I'll make a case that lambdas aren't really first class.

至于 lambda 是否是“一流的”,这实际上取决于您的定义,但我会说明 lambda 并不是真正的一流。

In some sense a lambda wants to be a function, but Java 8 is not adding function types. Instead, a lambda expression is converted intoan instance of a functional interface. This has allowed lambdas to be added to Java 8 with only minor changes to Java's type system. After conversion, the result is a reference just like that of any other reference type. In fact, using a Lambda -- for example, in a method that was passed a lambda expression as parameter -- is indistinguishable from calling a method through an interface. A method that receives a parameter of a functional interface type can't tell whether it was passed a lambda expression or an instance of some class that happens to implement that functional interface.

从某种意义上说,lambda 想成为一个函数,但 Java 8 没有添加函数类型。相反,一个 lambda 表达式被转换成一个函数式接口的实例。这使得 lambdas 可以添加到 Java 8 中,只需对 Java 的类型系统进行微小的更改。转换后的结果是一个引用,就像任何其他引用类型一样。事实上,使用 Lambda —— 例如,在一个将 lambda 表达式作为参数传递的方法中 —— 与通过接口调用方法没有区别。接收函数接口类型参数的方法无法判断它是传递了 lambda 表达式还是某个碰巧实现该函数接口的类的实例。

For more information about whether lambdas are objects, see the Lambda FAQ Answerto this question.

有关 lambda 是否为对象的更多信息,请参阅此问题的Lambda 常见问题解答。

Given that lambdas are converted into objects, they inherit (literally) all the characteristics of objects. In particular, objects:

鉴于 lambdas 被转换为对象,它们继承(字面上)对象的所有特征。特别是,对象:

  • have various methods like equals, getClass, hashCode, notify, toString, and wait
  • have an identity hash code
  • can be locked by a synchronizedblock
  • can be compared using the ==and !=and instanceofoperators
  • 有各种方法,例如equalsgetClasshashCodenotifytoString,和wait
  • 有一个身份哈希码
  • 可以被synchronized块锁定
  • 可以使用==!=instanceof运算符进行比较

and so forth. In fact, all of these are irrelevantto the intended usage of lambdas. Their behavior is essentially undefined. You can write a program that uses any of these, and you will get some result, but the result may differ from release to release (or even run to run!).

等等。事实上,所有这些都lambda 的预期用途无关。他们的行为基本上是未定义的。您可以编写使用其中任何一个的程序,您将得到一些结果,但结果可能因发行版而异(甚至运行到运行!)。

Restating this more concisely, in Java, objects have identity, but values (particularly function values, if they were to exist) should not have any notion of identity. Java 8 does not have function types. Instead, lambda expressions are converted to objects, so they have a lot baggage that's irrelevant to functions, particularly identity. That doesn't seem like "first class" to me.

更简洁地重申这一点,在 Java 中,对象具有标识,但值(特别是函数值,如果它们存在的话)不应该有任何标识的概念。Java 8 没有函数类型。相反,lambda 表达式被转换为对象,因此它们有很多与函数无关的包袱,尤其是身份。对我来说,这似乎不是“一流”。

Update 2013-10-24

更新 2013-10-24

I've been thinking further on this topic since having posted my answer several months ago. From a technical standpoint everything I wrote above is correct. The conclusion is probably expressed more precisely as Java 8 lambdas not being pure(as opposed to first-class) values, because they carry a lot of object baggage along. However, just because they're impure doesn't mean they aren't first-class. Consider the Wikipedia definitionof first-class function. Briefly, the criteria listed there for considering functions first-class are the abilities to:

自从几个月前发布我的答案以来,我一直在进一步思考这个话题。从技术角度来看,我上面写的一切都是正确的。结论可能更准确地表达为 Java 8 lambdas 不是纯值(与first-class相对),因为它们带有很多对象包袱。然而,仅仅因为它们不纯并不意味着它们不是一流的。考虑一等函数的维基百科定义。简而言之,此处列出的考虑功能一流的标准是以下能力:

  • pass functions as arguments to other functions
  • return functions from other functions
  • assign functions to variables
  • store functions in data structures
  • have functions be anonymous
  • 将函数作为参数传递给其他函数
  • 从其他函数返回函数
  • 将函数分配给变量
  • 在数据结构中存储函数
  • 有匿名函数

Java 8 lambdas meet allof these criteria. So that does make them seem first-class.

Java 8 lambdas 满足所有这些标准。所以这确实让他们看起来一流。

The article also mentions function names not having special status, instead a function's name is simply a variable whose type is a function type. Java 8 lambdas do not meet this last criterion. Java 8 doesn't have function types; it has functional interfaces. These are used effectively like function types, but they aren't function types at all. If you have a reference whose type is a functional interface, you have no idea whether it's a lambda, an instance of an anonymous inner class, or an instance of a concrete class that happens to implement that interface.

文章还提到函数名没有特殊地位,而是函数名只是一个类型为函数类型的变量。Java 8 lambdas 不符合最后一个标准。Java 8 没有函数类型;它有功能接口。它们像函数类型一样有效地使用,但它们根本不是函数类型。如果您有一个类型为函数式接口的引用,则您不知道它是 lambda、匿名内部类的实例还是碰巧实现该接口的具体类的实例。

In summary, Java 8 lambdas are more first-class functions than I had originally thought. They just aren't purefirst-class functions.

总而言之,Java 8 lambdas 是比我原先想象的更一流的函数。它们只是不是纯粹的一流功能。

回答by mikera

Yes, they are first class values (or will be, once Java 8 is released...)

是的,它们是一流的值(或者将是,一旦 Java 8 发布......)

In the sense that you can pass them as arguments, compose them to make higher order functions, store them in data structures etc. You will be able to use them for a broad range of functional programming techniques.

从某种意义上说,您可以将它们作为参数传递,将它们组合成更高阶的函数,将它们存储在数据结构中等等。您将能够将它们用于广泛的函数式编程技术。

See also for a bit more definition of what "first class" means in this context:

另请参阅有关“头等舱”在此上下文中的含义的更多定义:

回答by kan

As I see it, it is syntactic sugar, but in addition with the type inference, a new package java.util.functionsand semantic of inner classes it does appear as a first-class value.

在我看来,它是语法糖,但除了类型推断、java.util.functions内部类的新包和语义之外,它确实作为一流的值出现。

回答by Joop Eggen

A real closure with variable binding to the outside contexthas some overhead. I would consider the implementation of Java 8 optimal, sufficiently pure.

变量绑定到外部上下文的真正闭包有一些开销。我会考虑 Java 8 的最佳实现,足够纯。

It is not merely syntactical sugar at least.

至少它不仅仅是语法糖。

And I wouldn't know of any more optimal implementation.

而且我不知道任何更优化的实现。

回答by Roman Nazarevych

For me Lambdas in Java 8 is just syntax sugarbecause you cannot use it as First class Citizen (http://en.wikipedia.org/wiki/First-class_function) each function should be wrapped into object it imposes many limitation when comparing to language with pure first class function like SCALA. Java 8 closures can only capture immutable ("effectively final") non-local variables.

对我来说,Java 8 中的 Lambdas 只是语法糖,因为你不能将它用作 First class Citizen ( http://en.wikipedia.org/wiki/First-class_function) 每个函数都应该被包装成对象它在与具有纯一流功能的语言,如 SCALA。Java 8 闭包只能捕获不可变(“有效最终”)非局部变量。

Here is better explanation why it is syntax-sugar Java Lambdas and Closures

这是更好的解释为什么它是语法糖Java Lambdas and Closures