1、lambda含义
lambda表示数学符号“λ”,计算机领域中λ表明“λ演算”,表达了计算机中最基本的概念:“调用”和“置换”。在不少动态语言和C#中都有相应的lambda语法,这类语法都为了简化代码,提升运行效率。
2、lambda 项目的背景,参考这里。
不管是面向对象语言仍是函数式语言,基本数值均可以被动态的封装入程序动做:面向对象语言经过“方法”,函数式语言经过“函数。
介于“方法”和“函数”的定义有不少种,补充下IBM知识库的解释:
在面向对象语言中,方法不是一阶值(First-class value),在函数式语言中,函数是一阶值。在函数式语言中,函数能够做为另外一个函数的返回值或参数,还能够做为一个变量的值,函数能够嵌套定义,而在面向对象语言中的的“方法”作不到这点。
Java能够说是面向对象语言的表明,若是要调用其方法,须要先建立对象。不过Java对象都是“重量级”的,实例化具体的类的对象,须要通过定义和申明 两个阶段。好比定义方法,并给内部字段赋初始值。可是一个对象只包含一个方法的状况不少,好比实现API中的“回调接口”功能的类,在swing中有接 口:
Java代码
public interface ActionListener {
void actionPerformed(ActionEvent e);
}
现有的实现方式大可能是:
Java代码
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ui.dazzle(e.getModifiers());
}
});
不少现有的类库都基于这种设计实现,因此对于代码被明肯定义运行在单独线程的API来讲,匿名内部类尤其重要。这些匿名内部类只存在于建立它的线程中。但 是在并行计算领域,CPU的制造商着力发展多核技术来提高CPU的功能,这么作几乎没法依靠多核的优点来提高其性能。
鉴于回调函数和其余功能式语法的关系愈来愈密切,因此必须创建尽量的轻量级的数据模型(从编码角度而言,性能方面下文再说)。对于这点来讲匿名内部类的缺点以下:
1. 语法相对复杂。
2. 在调用内部类的上下文中,指引和this的指代容易混淆。
3. 类加载和实例建立语法不可避免。
4. 不能引用外部的非final对象。
5. 不能抽象化控制流程
针对这些问题,lambda项目致力于
1. 消除问题1和问题2,经过引入更简单的表达式和局部变量的定义规则。
2. 回避问题3,定义更灵活更友善的语法。这里只是回避,类加载和实例化自己不可避免。下文会解释。
3. 改善问题4,容许用户使用最终有效的局部变量。
不过lambda项目目前并不能解决全部关于内部类的问题。问题4和问题5没有彻底解决,这计划在将类版本中继续改善。对于性能方面,原文也没有提,不事后面有些补充。
3、lambda用法
经过上文能够了解到,lambda语法是针对“回调接口”和“匿名内部类”做出的改进,因此lambda的语法目前仅对于部分接口,这些接口的特色是只含 一个抽象方法,在lambda项目中,早期称为SAM类型(SAM = single abstract method 即单一抽象方法)。在最新的文档中(即这个版本),它们有了新名字,叫函数接口(functional interface),好比:
1 java.lang.Runnable
2 java.util.concurrent.Callable
3 java.security.PrivilegedAction
4 java.util.Comparator
5 java.io.FileFilter
6 java.nio.file.PathMatcher
7 java.lang.reflect.InvocationHandler
8 java.beans.PropertyChangeListener
9 java.awt.event.ActionListener
10 javax.swing.event.ChangeListener
lambda的语法包括三部分
一、参数列表
二、箭头符号"->"
三、代码块。
其中代码块很像一个方法体,return语句将控制权交还给匿名方法(anonymous method,即lambda表达式)的调用者;break和continue不能出如今函数体的顶部,不过能够出如今内部的循环里;若是代码块得出最终 结果,那么每个控制路径(control path) 必须都有返回或抛出异常。
若是代码块只有简单一行,能够省略return关键字和“{}”符号(如下所写的例子都是基于JDK 1.8 lambda预览版),好比:
Java代码
public class LambdaTest {
public static void main(String... args) {
//这里有{}和return 以及 ;
Runnable r = () -> { System.out.println("hello world"); };
//这里不须要{}和return
java.util.Comparator<String> c = (String s1, String s2) -> s2.length()-s1.length();
r.run();
System.out.println(c.compare("s1", "12323"));
}
}
输出为:
hello world
3
除了这些现有接口,咱们还能够自定义函数接口:
Java代码
public class LambdaTest {
interface lambdaInterface {
public void me(String str);
}
public static void main(String... args) {
lambdaInterface li = (String s)->{System.out.println(s);};
li.me("hello world!");
}
}
输出为:
hello world!
新的lambda方法从语法上的确是简化了不少。和lambda第一次发布的语法相比也优雅不少。java