Lambda 来源于希腊字母入,
发音为 /'læmdə/
对高数有所了解的人都知道λ用于声明一个数学逻辑系统, 表示根据 XX 的输入参数, 会返回某个 Y 结果. 这正是编程语言中函数 (方法) 的意思.
因此 Lambda 表达式在编程语言中说白了就是指的一个方法表达式.
为什么要搞出这么一个东西来呢? 这是由于我们的编程语言都是按照面向对象设计的, 也就是我给你提供几个对象, 你给我返回几个对象, 但是有时候我们仅仅是把一些算法逻辑传来传去. 并不需要一个对象这么完整的结构.
OO 语言常用的写法就是把这段算法逻辑作为对象中的某个方法, 然后再把这个对象传来传去. 这样做固然没问题, 但是却对开发人员并不友好, 由于大量的冗余代码, 导致阅读起来有时候非常费劲. 于是编程语言的设计人员就搞出这样一个 Lambda 表达式, 允许算法逻辑 (方法) 作为一个可传递的对象, 进行传递.
Lambda 表达式很早就开始出现在其他语言中了, 如 Lisp,C#(这里不得不提到 C# 设计的优越性, 也说明设计一款编程语言的难度是非常大的. 设计的超前了, 可能很多人掌握不了如何用. 设计的滞后了, 很多人又不屑于用).Java 是在 Jdk8 中开始引入的这个特性, 诣在帮助 java 开发人员从冗余的代码开发中解脱出来.
在说 Lambda 表达式之前, 我们要先引入一个概念:
函数式接口
什么是函数式接口呢?
就是只定义了一个抽象方法的接口, 我们可以使用注解 @Functionallnterface, 来强约束这种接口为函数式接口.
大家可以翻看下 jdk8 的源码,(防盗连接: 本文首发自 http://www.cnblogs.com/jilodream/ )如 Runnable,Callable,Comparator 等早期的接口都补充添加了这个注解. Lambda 表达式就是专门用来实现这些函数式接口的表达式, 这点非常重要.
- @FunctionalInterface
- public interface Runnable {
- public abstract void run();
- }
下面我们进入正题, 应该怎么写 Lambda 表达式呢?
我们如果想用 Runnable 起个线程, 需要这样写:
- Runnable runnable = new Runnable()
- {
- @Override
- public void run()
- {
- // TODO
- }
- };
- new Thread(runnable).start();
也就是起一个内部匿名类实现接口中的方法, 然后再操作. 其实质就是把一段逻辑包含到 run 方法中, 扔给线程去执行.
但是 Lambda 表达式则可以直接作为一个函数表达式来替代这个内部类.
- Runnable runnable = ()->
- {
- // dosth
- };
- new Thread(runnable).start();
在这个例子中, 我们可以发现 Lambda 表示有三部分构成:
1, 参数列表: 与接口中方法的参数列表要求一致
2, 箭头:-> 由横线和大于号构成
3, 方法体: 和方法的方法体要求是一样的.
同时 Lambda 为了更加简洁的 (防盗连接: 本文首发自 http://www.cnblogs.com/jilodream/ ) 做了如下几个改进点:
1, 参数列表中的参数类型可以直接都忽略掉不写.(注意是参数类型, 不是参数. 因为只有一个抽象方法, 参数类型是可以直接推导出来的)
2, 如果只有一个参数, 圆括号也可以省略.
3, 方法体如果只有一语句, 可以省略掉大括号.
4, 如果仅有一条语句, 并且他是 return 语句的话, 那么可以直接省略掉 return 关键字.
直接看下边的例子:
- import java.util.List;
- @FunctionalInterface
- public interface ICommand
- {
- List<Integer> process(Integer[] target);
- }
- import java.util.List;
- public class ProcessArray
- {
- public List<Integer> process(Integer[] target, ICommand cmd)
- {
- return cmd.process(target);
- }
- }
- import java.util.Arrays;
- import java.util.List;
- public class JavaLambda
- {
- public static void main(String[] args)
- {
- ICommand cmd = tt -> Arrays.asList(tt);
- ProcessArray processArray = new ProcessArray();
- List<Integer> list2 = processArray.process(new Integer[]
- { 1, 2, 3, 4, 5, 6, 7 }, cmd);
- }
- }
我们可以发现 JavaLambdal 类中, 第 8 行代码处, 等号右侧:
1, 没有声明参数的类型
2, 没有参数列表的圆括号
3, 方法体没有大括号
4, 方法体没有 return 关键字
例子举的很简单是希望 (防盗连接: 本文首发自 http://www.cnblogs.com/jilodream/ ) 大家能看明白, 但是要学会还是要靠自己动手写几个例子.
下篇文章我会写一下下 lambda 表达式更精简的用法: 如何利用已有的方法引用以及 java 中 lambda 表达式和内部类使用起来的异同等.
来源: https://www.cnblogs.com/jilodream/p/10646441.html