目录
1,lambda 概念
2,lambda 基本语法
2.1, 基本概念
2.2, 语法格式
3,Lambda 表达式例子
1,lambda 概念
java8 它可以让我们用简洁流畅的代码完成一个功能.
很长一段时间 java 被吐槽是冗余和缺乏函数式编程能力的语言, 随着函数式编程的流行 java8 种也引入了 这种编程风格.
在此之前我们都在写匿名内部类干这些事, 但有时候这不是好的做法, 本文中将介绍和使用 lambda, 带你体验函数式编程的魔力
lambda 表达式是一段可以传递的代码, 它的核心思想是将面向对象中的传递数据变成传递行为.
我们回顾一下在使用 java8 之前要做的事, 之前我们编写一个线程时是这样的:
- Runnable r = new Runnable() {
- @Override
- public void run() {
- System.out.println("do something.");
- }
- }
也有人会写一个类去实现 Runnable 接口, 这样做没有问题, 我们注意这个接口中只有一个 run 方法, 当把 Runnable 对象给 Thread 对象作为构造参数时创建一个线程, 运行后将输出 do something.. 我们使用匿名内部类的方式实现了该方法
这实际上是一个代码即数据的例子, 在 run 方法中是线程要执行的一个任务, 但上面的代码中任务内容已经被规定死了. 当我们有多个不同的任务时, 需要重复编写如上代码
设计匿名内部类的目的, 就是为了方便 Java 程序员将代码作为数据传递. 不过, 匿名内部 类还是不够简便. 为了执行一个简单的任务逻辑, 不得不加上 6 行冗繁的样板代码. 那如果是 lambda 该怎么做?
Runnable r = () -> System.out.println("do something.");
嗯, 这代码看起来很酷, 你可以看到我们用 () 和 ->的方式完成了这件事, 这是一个没有名字的函数, 也没有人和参数, 再简单不过了. 使用 ->将参数和实现逻辑分离, 当运行这个线程的时候执行的是 ->之后的代码片段, 且编译器帮助我们做了类型推导; 这个代码片段可以是用 {} 包含的一段逻辑. 下面一起来学习一下 lambda 的语法.
2,lambda 基本语法
2.1, 基本概念
expression = (variable) -> action
variable: 这里是一个变量, 一个占位符, 像 x,y,z, 可以是多个变量, 也就是说左侧是 lambda 表达式的参数列表
action: 这里我称它为 action(也就是表达式中所需执行的功能), 这是我们实现的代码逻辑部分, 它可以是一行代码也可以是一个代码片段
可以看到 Java 中 lambda 表达式的格式: 参数, 箭头, 以及动作实现, 当一个动作实现无法用一行代码完成, 可以编写 一段代码用 {} 包裹起来
lambda 表达式可以包含多个参数
int sum = (x, y) -> x + y;
这时候我们应该思考这段代码不是之前的 x 和 y 数字相加, 而是创建了一个函数, 用来计算两个操作数的和. 后面用 int 类型进行接收, 在 lambda 中为我们省略去了 return
2.2, 语法格式
语法格式一: 无参数, 无返回值
Runnable runnable1 = () -> System.out.println("lambda 表达式");
语法格式二: 有一个参数, 无返回值
- // Consumer 接口可以查看源码
- Consumer<String> consumer = (x)-> System.out.println(x);
- consumer.accept("有参数的 lambda 表达式");
语法格式三: 若只有一个参数, 小括号可以不写省略
- Consumer<String> consumer = x-> System.out.println(x);
- consumer.accept("有参数的 lambda 表达式");
语法格式四: 有两个参数以及以上参数, 有返回值, 方法体多条语句
- Comparator<Integer> comparator1 = (x, y) -> {
- System.out.println(x + y);
- return Integer.compare(x,y);
- };
语法格式五: 如果 lambda 体中只有一条语句, return 和大括号都可以省略不写
Comparator<Integer> comparator1 = (x, y) -> Integer.compare(x, y);
语法格式六: Lambda 表达式的参数列表的数据类型可以省略不写, 因为 JVM 编译器通过上下问推断出数据类型 --- 类型推断
Comparator<Integer> comparator1 = (x, y) -> Integer.compare(x, y);
3,Lambda 表达式例子
如下的代码我们仔细阅读
函数型接口
- @FunctionalInterface
- public interface MyFunction<T> {
- public Integer getValue(Integer num);
- }
上面的代码, 我们定义了一个函数型的接口, 该接口存在一个抽象方法, 该方法的具体实现由我们自己实现
调用
- public class TestLambda02 {
- public static void main(String[] args) {
- Integer value = operation(100, x -> x * 2);
- System.out.println(value);
- }
- public static Integer operation(Integer num, MyFunction mf) {
- return mf.getValue(num);
- }
- }
上面代码中, 对于函数型接口 MyFunction, 我们采用了自定义实现 x->x*2, 由此可以发现 lambda 表达式就是一段可以传递的代码
来源: http://www.bubuko.com/infodetail-3653605.html