Lambda
lambda表达式(jdk1.8)
函数编程思想
描述
强调的是作生么,而不是以什么样的方式来做,它忽略了面向对象的复杂语法,只要能够获取到结果,谁去做,怎么做的,都不重要重要的是结果,不重视过程。
冗余的Runnable代码
//传统的写法 public class Demo{ public static void main(String[] args){ //匿名内类的格式 new Thread(new Runnable(){ @Override public void run(){ System.out.pringln("开启了一个新线程任务"); } }).start(); } } //对于Runnable的匿名内部类用法,可以分析一下内容: Thread类需要Runnable接口作为参数,其中的抽象方法run用来指定线程任务内容的核心。 为了指定run方法的方法体,不得不需要Runnable接口的实现类。 为了省去定义一个Runnable Impl实现类的麻烦,不得不使用匿名内部类。 必须重写抽象方法run,所以方法的名称,参数返回值不得不再写一遍,且不能写错。 从这里看出来,'只有方法体才是线程任务的关键性内容'。
编程思想的转换
强调的是做什么,而不是怎么做
我们希望做的事情是,将run方法内的代码传递给Thread类知晓能够加载即可。
传递代码 --》这是我们真正的目的
我们需要将程序的重点从怎么做回归到做什么本质上,过程于形式不重要。
2014年Oracle官方发布java 8 中,加入了Lambda表达式,可以取代大部分的匿名内部类,写出更优雅的代码
//优化刚才的代码 new Thread(() -> { System.out.println(Thread.currentThread().getName() + "-->"); }).start(); // 省略模式需要三项一起省略{} ; new Thread(() -> System.out.println(Thread.currentThread().getName()+ "-->")).start(); //冲上面代码看出;没有创建实现类对象的操作,也不再有抽象方法覆盖重写的操纵,只写了线程的任务内容。
Lambda语法
()->System.println("开启了一个新线程");
()前面的一对小括号即为run方法,参数为空,里面的时空,此时需要任何的条件
-> 中间的一个箭头宝石前面的参数传递给后面的代码
{} 后面的输出语句即为业务逻辑代码(线程任务代码)
Lambda标准格式
格式由三部分组成
一些参数
一个箭头
一段代码
(参数类型1,参数名称1,参数类型2,参数名称2...) ->{代码语句}
格式说明
小括号内的语法与传统的方法参数列表一致,无参数就留空,多个参数则用参数则用逗号隔开。
-> 是新引入的语法格式,代表指向的动作。
大括号的语法与传统方法要求一致。
横批:能省则省
左联: 左右遇一括号省
右联: 左侧推断类型省
使用Lambda格式练习
//(无参无返) public class LambdaDemo4 { public static void main(String[] args) { //参数被省略了 ad(()-> System.out.println(12)); } //用一个方法采用 public static void ad(AA aa) { aa.show(); } } interface AA { void show(); } *************************************************************************************************************** //(有参有返) public class LambdaDemo3 { public static void main(String[] args) { //Lambda表达式 invokeSum(3.2, 2.2, (double a, double b) -> { //带有返回值 return a + b; }); //采用匿名内部类写法 invokeSum(3.2, 2.2, new Calc() { @Override public double sum(double a, double b) { return 3.2 + 2.2; } }); } //定义方法 //参数 传递两个double值 // 传递一个calc接口方法 // 内部调用了sum方法 public static void invokeSum(double a, double b, Calc calc) { double sum = calc.sum(a, b); System.out.println(sum); } } //定义一个结算器,内置了一个抽象方法sum(d d1,d d2) interface Calc { //定义一个求和的方法 double sum(double a, double b); }
练习
public class LambdaDemo6 { public static void main(String[] args) { /* 语法形式为 () -> {} 其中 () 用来描述参数列表 {} 用来描述方法体 -> 为 lambda运算符 ,读作(goes to)。 */ //1.简化参数类型,可以不写参数类型,但是必须所有参数都不写 N1 n1 = (int a, int b) -> { System.out.println("多参无返被调用,他们的何为" + (a + b)); }; n1.method(12, 34); //------------------------------------------------------- //2.简化参数小括号,如果只有一个参数则可以省略参数小括号 N2 n2 = () -> { System.out.println("无参无返方法被调用"); }; n2.method(); //------------------------------------------------------- //3.简化方法体大括号,如果方法只有一条语句,则可以省略方法的大括号 N3 n3 = (int a) -> { System.out.println("有一参无返被调用了," + a); }; n3.method(13); //------------------------------------------------------- //4.如果方法体只有一条语句,并且是return语句,则可以省略方法体的大括号 R4 r4 = (int a, int b) -> { return a - b; }; System.out.println("多参有返被调用了," + r4.method(34, 21)); //------------------------------------------------------- R5 r5 = () -> { return 12; }; System.out.println("无参有返被调用了," + r5.method()); //------------------------------------------------------- R6 r6 = (int a) -> { return a; }; System.out.println("一个参数有返被调用了" + r6.methon(12)); } } //多参数无返会 interface N1 { void method(int a, int b); } //无参无返回值 interface N2 { void method(); } //一个参数无返回 interface N3 { void method(int a); } //多个参数有返回值 interface R4 { int method(int a, int b); } //无参有返回 interface R5 { int method(); } //一个参数有返回值 interface R6 { int methon(int a); }
Lambda省略格式
//可推导即可省略 //Lambda强调的是做什么,而不是怎么做,凡是可以根据上下文推到得知的信息,都可以省略。 invokeSum(3.14,3.15,(double a,double b)->{ return a+b; }); //省略格式 invokeSum(3.14,3.15,(a,b) -> a+b); //在Lambda标准表达式省略规则; 1.小括号内参数的类型可以省略。 2.如果小括号内有且仅有一个参数,则小括号也可以省略。 3.如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号,return关键字和语句的分号。
Lambda的使用前提
Lambda的语法非常间接,使用非常间的简单,但是有一下注意事项
1.使用Lambda必须有接口,并且要求仅有一个抽象方法
2.使用Lambda必须具有上下文推断。
当有且仅有一个抽象方法的接口,称为函数接口