一、Lambda表达式:
引子:在学习之前我们首先看两段代码
上面展示两份代码 实现功能一样 但是明显感觉到使用Lambda表达式 书写代码更加简洁 便于阅读理解。
Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。
JDK 也提供了大量的内置函数式接口供我们使用,使得 Lambda 表达式的运用更加方便、高效。
/**
* @author zhu
* @date 2021/7/7 16:17
*/
public class MyTest {
/**多参数无返回*/
@FunctionalInterface
public interface NoReturnMultiParam { void method(int a, int b); }
/**无参无返回值*/
@FunctionalInterface
public interface NoReturnNoParam { void method(); }
/**一个参数无返回*/
@FunctionalInterface
public interface NoReturnOneParam { void method(int a);}
/**多个参数有返回值*/
@FunctionalInterface
public interface ReturnMultiParam { int method(int a, int b);}
/*** 无参有返回*/
@FunctionalInterface
public interface ReturnNoParam { int method();}
/**一个参数有返回值*/
@FunctionalInterface
public interface ReturnOneParam { int method(int a);}
public static void main(String[] args) {
/**
* Lambda的标准格式
* lambda表达式是一个匿名的函数,函数相当于java中的方法
*
* (参数列表) -> { 方法体 }
* -> 没有实际含义,起到连接作用
* lambda运算符 ,读作(goes to)。
*/
//1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
NoReturnMultiParam lamdba1 = (a, b) -> { System.out.println("简化参数类型"); };
lamdba1.method(1, 2);
//2.简化参数小括号,如果只有一个参数则可以省略参数小括号
NoReturnOneParam lambda2 = a -> { System.out.println("简化参数小括号"); };
lambda2.method(1);
//3.简化方法体大括号,如果方法条只有一条语句,则可以胜率方法体大括号
NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
lambda3.method();
//4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
ReturnOneParam lambda4 = a -> a+3;
System.out.println(lambda4.method(5));
ReturnMultiParam lambda5 = (a, b) -> a+b;
System.out.println(lambda5.method(1, 1));
}
}
@FunctionalInterface 给大家解释一下该注解哈:
常用的一些接口Callable、Runnable、Comparator等在JDK8中都添加了@FunctionalInterface注解。
通过JDK8源码javadoc,可以知道这个注解有以下特点:
1、该注解只能标记在"有且仅有一个抽象方法"的接口上。
2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
4、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
总结Lambda表达式和匿名内部类区别:
二、Lambda 方法引用:
用lambda创建了函数式接口的实现类对象,正好lambda要写的抽象体是其他方法的方法体
语法 :方法归属者::方法名 静态方法的归属者为类名,普通方法归属者为对象
构造方法的引用:
一般我们需要声明接口,该接口作为对象的生成器,通过 类名::new 的方式来实例化对象,然后调用方法返回对象。
/**
* @author zhu
* @date 2021/7/7 17:44
*/
public class MyTest01 {
interface zhu {
int run(String string);
}
public static void main(String[] args) {
/**
* 实质代码
*/
getInteger("123", (str) -> Integer.parseInt(str));
/**
* 使用方法引用
*/
int i = getInteger("123", Integer::parseInt);
System.out.println(i);
}
public static int getInteger(String str, zhu z) {
return z.run(str);
}