java - 我无法理解 lambda 表达式在 Java 中的工作原理
问题描述
我介于初学者和中级 Java 程序员之间,几天前,函数式编程的神秘概念引起了我的注意。我习惯于 OOP 实践,并且没有关于在 Java 中使用 lambda 表达式对我的影响。下面是我的困惑的一个例子
Runnable r1 = new Runnable() {
@Override
public void run () {
System.out.println("Prior to Java 8");
}
};
//Runnable using lambda expression
Runnable r2 = () - > {
System.out.println("From Java 8");
};
我不知道将 r2 分配给 lambda 表达式应该是什么意思。接口的整个对象是如何分配给只打印出一条消息的代码块的?函数式编程的抽象级别对我来说几乎没有意义,任何回复都将不胜感激。
解决方案
本质上,您的第二个块 ( r2
) 是语法糖。请注意其中的内容r2
是如何少得多的文本。如果你比较,它会变得更好,比如:
Comparator stringLength = new Comparator<String>() {
public int compare(String a, String b) {
return a.length() - b.length();
}
};
相对:
Comparator stringLength = (a, b) -> a.length() - b.length();
但让我们先集中注意力r1
。
这本身也是语法糖!它的简称:
public void methodWeAreIn() {
class MethodLocalClassWithoutAnImportantName implements Runnable {
public void run() { System.out.println("boo"); }
}
Runnable r1 = new MethodLocalClassWithoutAnImportantName();
}
关键是:您首先定义一个类,然后创建该类的单个实例,然后丢弃它的特定类型性质(将其分配给 type 的变量Runnable
。就像 in 一样List<String> x = new ArrayList<String>();
,您失去了调用trimToSize
和ensureCapacity
,这些方法仅存在于 ArrayList 中,而不存在于 List 本身中。)这不是一件坏事:在这个特定的代码段中,这并不重要。
这就是重点:这里的类型 ( MethodLocalClassWithoutAnImportantName
)与类型完全无关——代码库中的任何方法都没有将其中一个作为参数,也没有方法返回它。它就像一个反接口:接口的存在只是为了有一个类型来实现或放入方法签名(作为返回类型或参数)。这堂课的重点是相反的。重点不在于类结构。这个类的重点仅仅是它里面的实现。毕竟这是 OO 的一部分——有时你实现了一个接口并且没有定义任何新的方法或字段,你只是在实现接口并且可能覆盖超类中的东西。
重新考虑这一切意味着什么更为明智。您并没有定义一个新类然后创建一个实例。你实际上只是拿了一些代码,而不是运行它,你把它塞进一个信封里。
现在你可以把这个信封交给另一个方法(它可以选择也交给它,或者打开它并运行它),或者重复运行它,或者稍后在另一个线程中运行它等等。是的,在r1
(以及我的方法本地类示例),“信封”是一个对象,但这只是一种方便的方法,练习的重点不是创建新类型,而是编写可以四处传播的代码。
Lambdas 只是让那个正式的。
注意:r2
不是精确的语法糖;但是除非你做你不应该做的事情,否则你无法区分:尝试将 r2 视为具有标识的对象。如果你synchronized (r2)
,或者尝试类似的事情System.identityHashCOde(r2);
,会发生奇怪的事情。关键是不要那样做。你为什么想要?
推荐阅读
- asp.net - 是否可以将 Microsoft.Aspnet.Identity.Core 与 .net 4.0 一起使用
- python - 检查 GPS 字符串格式
- image - 重塑图像错误:“元组”对象不能解释为整数
- azure-vpn - 无法使用虚拟 WAN 创建点到站点连接
- jquery - 用于父选择的 jQuery
- ruby - 使用 Ruby 验证 Ruby 语法
- git - gitlab自动部署期间如何保持文件权限?
- codenameone - 具有枚举属性的 PropertyBusinessObject
- php - Yii2 $model->_attributes 分配在新版本中不起作用
- c# - MagickImage - 无法读取 TIFF 图像