整理了长风老师在Day11的lambda章节的随堂代码
匿名内部类之lambda表达式1.
package com.cskaoyan.javase.oop3.innerclazz6.lambda6.introduction1;
/**
* @description: lambda的引入
* @author: 长风老师
**/
/**
* 目的:简洁。取代接口的匿名内部类,简化了局部内部类
*
* 【1.】目的:取代接口的匿名内部类
* 不能取代普通类和抽象类的匿名内部类
*
* 【2.】前提,对接口有严格的要求:
* 接口有且仅有一个抽象方法需要子类实现
* ---这种接口被称之为功能接口(function interface)
* ---功能接口像方法的重写一样,可以用注解检测
* @FunctionInterface 如果注解不报错该接口就是功能接口
* 该注解直接写在接口定义的头上面
*
* 需要注意的是: java8以后接口引入了实现方法:默认方法和静态方法不需要子类实现,
* 所以功能接口不意味着只有一个方法,可以有实现方法
* 但是普遍来说,没有人在功能接口中写实现方法,这一点了解即可
*
* 【3.】语法:lambda表达式是在方法内部用来创建功能接口的实现类对象
*
* 语法: (1)形参:
* ()中是形参列表,无需传入实际参数
* (2)运算符:
* -> 是lambda运算符 可以读作goes to
* (3)方法体:
* {} 中放的是抽象方法重写的方法体
*
* lambda语法中形参列表只有一个 方法体也只有一个 没办法重写两个方法 只能重写一个
*
* 【4.】识别数据类型
* 直接在方法中,写完这个语法后,程序报错
* () -> {
* System.out.println("hello world!");
* }; 表示的是接口的实现类对象
* 它报错的原因 首先java是强类型语言,每个变量都是有数据类型的
* 但是如果这么光秃秃的写,编译器无法得知这个对象的数据类型,无法知道他是谁的实现类对象
*
* 【5.】lambda表达式的类型推断
* 怎么做类型推断呢?
* 需要通过额外的信息做推断,根据上下文代码推断
* 需要写额外的代码帮助编译器推断
*
* (1)直接告诉你该对象的类型,直接用接口引用 指向它
* (2)直接告诉类型,但是不接收它,仅仅告诉他
* 这种形式没有引用接收,如果你不直接使用,该lambda表达式没有意义,语法上不允许不适用
* (3)根据方法的形参列表推断
* (4)根据方法的返回值推断
*
*
*/
public class Demo {
public static void main(String[] args) {
IA ia = () -> {//【1.】直接告诉对象类型,用接口引用
System.out.println("hello world!");
};
ia.test();
((IA) () -> {//【2.】直接告诉对象类型,不接收。要直接使用,比如加.
System.out.println("hello 王大锤!");
}).test();
method().test();//【4.】根据方法返回值
method(() -> {//【3.】根据方法形参列表
System.out.println("hello 张三");
});
}
public static IA method(){
//这里编译器已经知道要返回IA接口的实现类对象【4.】根据方法返回值
return () -> {
System.out.println("hello kitty");
};
}
public static void method(IA ia){//【3.】根据方法形参列表
ia.test();
}
}
@FunctionalInterface
interface IA {
void test();
}
@FunctionalInterface
interface IB {
void test();
}
匿名内部类之lambda表达式2.
package com.cskaoyan.javase.oop3.innerclazz6.lambda6.basic2;
/**
* @description: lambda表达式更进一步简洁
* @author: 长风老师
**/
/**
* lambda表达式继续简写
* lambda表达式的目标接口,有且仅有一个抽象方法,这是lambda表达式继续简化的前提
* (形参列表) -> {方法体}
* 【1.】(形参列表)的简化:
* 知道用哪个接口 哪个抽象方法
* 所以形参列表中的数据类型是多余的,可以省略的
* 更进一步,如果这个参数只有一个
* 那么这个小括号式多余的。但是如果没有参数和多个参数,不可省略小括号
*
* 【2.】{方法体}的简化:
* (1)if、for如果语句只有一条可以省略大括号
* (2)如果重写的方法的方法体只有一条语句,也可以省略大括号
* (3)如果这个抽象方法是有返回值的且它的返回值语句只有一行,那么return不需要
*
* 【3.】更进一步:直接把方法的实现 指向一个已经存在的方法
* 判断已存在的方法和功能接口中的抽象方法一样呢?
* 看返回值类型和形参列表
* 语法:
* (接口中那个抽象方法的形参列表) -> 已实现的某个方法
*
*
* 【4.】更进一步:
* 方法归属者::方法名
* 直接不写小括号,运算符也不要了
* 直接=
* 怎么判断一个方法的归属者呢?
* 成员方法,属于对象,所以需要先创建对象 再指向
* 静态成员方法,属于类,直接类名放上去
* 这种指向已实现的方法 还可以指向jdk中源码已存在的方法 注意方法的归属即可
*
* lambda表达式对象没有自己单独的作用域,和方法共享作用域
*
*
> lambda表达式的优缺点
- 优点:
- 极大得简化了代码,使代码变得更加优雅
- 函数式编程的代表,可能是未来高端的编程趋势
- 缺点:
- 过于简单的lambda表达式,显然可读性很低
*
*/
public class Demo {
public static void main(String[] args) {
//【0.】标准格式lambda式创建双参数抽象方法接口的子类对象
INoReturnTwoParam ip0 = (int a, int b) -> {
System.out.println("a + b =" + (a + b));
};
ip0.test(2,2);//4
//【1.】省略数据类型
INoReturnTwoParam ip1 = (a, b) -> {
System.out.println("a + b =" + (a + b));
};
ip1.test(2, 2);//4
//【1.更进一步】单参数可以去掉小括号
INoReturnOneParam ip2 = a -> {
System.out.println("a = " + a);
};
ip2.test(888);//a = 888
//【2.1】if或for只有一个分支,或者方法体只有一条语句,可以省略大括号。初级。
INoReturnOneParam ip3 = a -> System.out.println("a = " + a);
ip2.test(888);//a = 888
//【2.2】原来:返回值是一行
IHasReturnNoParam ip41 = () -> {
return 10;
};//10
//【2.2】现在:简化
IHasReturnNoParam ip42 = () -> 10;
System.out.println(ip42.test());//10
//【3.】方法实现指向已经存在的方法
INoReturnNoParam ip51 = () -> method();;
ip51.test();//hello world
//【3.】简化:
INoReturnNoParam ip52 = Demo::method;
ip52.test();//hello world
//【4.归属者::方法名】
Demo d = new Demo();
INoReturnNoParam ip6 = d :: method2;
ip6.test();//张三
//System.out.println();
INoReturnNoParam ip7 = System.out :: println;
ip7.test();//这个输出空行
}
public static void method() {
System.out.println("hello world!");
}
public void method2(){
System.out.println("hello 张三");
}
}
//无返回值无参数的功能接口
@FunctionalInterface
interface INoReturnNoParam {
void test();
}
//无返回值有一个参数的功能接口
@FunctionalInterface
interface INoReturnOneParam {
void test(int a);
}
//无返回值两个参数的功能接口
@FunctionalInterface
interface INoReturnTwoParam {
void test(int a, int b);
}
//有返回值无参数的功能接口
@FunctionalInterface
interface IHasReturnNoParam {
int test();
}
//有返回值一个参数的功能接口
@FunctionalInterface
interface IHasReturnOneParam {
int method(int a);
}
//有返回值两个参数的功能接口
@FunctionalInterface
interface IHasReturnTwoParam {
int test(int a, int b);
}