首先,希望大家能看完,并且自己尝试写一下文章里的示例,不自己写代码很难理解Lambda表达式
1.Lambda表达式的概述
Lambda体现的是函数式编程思想,在一定程度上简化了代码,但同时也有着一定的局限性。
Lambda表达式是简洁的,而且在并行计算时,效率可能会比for更高,在lambda表达式中使用外部定义的局部变量的时候,局部变量不再必须是final型的。
Lambda表达式用途局限,只能用于接口中,且在接口中只有一个接口方法的时候有用。
Lambda表达式的标准模式是:(参数列表) -> {代码}
这表示的是,Lambda表达式中的参数列表对应的就是接口方法的参数列表,对应的代码块就是对接口抽象方法的重写,这里你可能无法理解,等下看一下例子就懂了。
表达式的参数与一般的方法参数列表一样,没有参数就留空,有多个参数就用逗号分隔,其中不需要声明参数类型,编译器可以统一识别参数值。一个参数不用定义圆括号,可以直接 参数 -> {代码},但多个参数需要定义圆括号。
如果主体只包含了一个语句,就不需要使用大括号。类似for与while。
关于返回值:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回一个值。
2.Lambda表达式的例子讲解
1.启动线程
public class LambdaTest1 { public static void main(String[] args) { // 一般写法 new Thread(new Runnable() { @Override public void run() { System.out.println("this is a thread"); } }).start(); // Lambda表达式写法 new Thread(() -> { System.out.println("this is a thread"); }).start(); } }
编辑
Lambda表达式写法中,()就是run的形参列表,{}里就是代码实现。是一种简写。可以理解为一般写法的简化,少写了一些不那么重要的,只需要强调函数实现。
其中,Runnable的接口如下,仅有一个抽象方法,其中,@FunctionalInterface注解表明这是一个函数式接口(只包含一个抽象方法的接口,称为函数式接口)。 编辑
2.比较器的使用
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class LambdaTest2 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); Collections.addAll(list,1,8,6,4,3,2,6,3); System.out.println("排序前:" + list); // 咱们正常写的比较器 Collections.sort(list, new Comparator<Integer>() { @Override public int compare (Integer o1, Integer o2) { return o2-o1; } }); // Lambda表达式写的比较器 Collections.sort(list,(Integer o1, Integer o2)->{return o2-o1;}); // 这样写也是对的 // Collections.sort(list,(Integer o1, Integer o2)-> o2-o1); System.out.println("排序后:" + list); } }
编辑
其中,绿色框内可以看为是省略的。因为我们使用Lambda表达式的时候就知道,这里调用的是什么接口,Java调用的就是这个抽象接口的那个唯一的抽象方法,也就不需要再强调一遍写的是什么东西了。这样就简化了代码。
以下是Comparator接口内容,这一看,好像不对啊,怎么这么多方法?别忘了我们说的函数式接口的要求是:只包含一个抽象方法的接口。默认方法不是抽象方法,除此之外,Comparator中仅剩static方法了。所以Comparator是一个函数式接口。Lambda执行的就是第一个compare。
不仅如此,函数式接口里还允许包含java.lang.Object 里的 public 方法。比如equals, toString,hashcode方法。 编辑
3.自己练习
public class LambdaTest{ public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest(); lambdaTest.sout(() -> { System.out.println("Lambda Expression"); }); } public void sout(A a){ a.sout(); } } interface A{ public void sout(); }
运行main,会输出
Lambda Expression
那么。这个时候,可能有朋友要问了:我想在sout方法中自定义我想输出的内容,我该怎么办呢?
我在下面给大家提供一种方法,用于修改输出:
public class LambdaTest{ static String str = "This is "; public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest(); lambdaTest.print((name) -> { System.out.println(name + "Lambda Expression"); }); } public void print(A a){ a.sout(str); } } interface A{ public void sout(String s); }
编辑此处通过修改全局变量str的值可以改变print的输出。例子2的Collection也类似于如此,传入一个Comparator c后通过改变c的方法的值,以此来实现比较操作。
推荐大家自己DeBug一下看一看他们的实现过程,加深自己的理解。我在此写下的难免有些疏漏,欢迎大家补充指正,共同进步!