版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
Lambda表达式
在JDK8以前,方法能接收的参数都是变量,JDK8之后,支持将函数作为参数传递。
/**
* @Description: 接口
*/
@FunctionalInterface
public interface Simple {
void callback();
}
JDK8之前
/**
* @Description: 客户端测试
*/
public class Client {
public static void main(String[] args) {
Simple simple = new Simple() {
@Override
public void callback() {
System.out.println("java7 callback...");
}
};
simple.callback();
System.out.println(simple.getClass().getName());
}
}
输出:
java7 callback...
com.ch.java8.lambda.Client$1
创建匿名内部类,实现接口方法,然后调用。
“匿名”是针对开发者而言,对于JVM来说,匿名内部类 仍然有名字。
JDK8
/**
* @Description: 客户端测试
*/
public class Client {
public static void main(String[] args) {
simple = () -> System.out.println("lambda callback...");
simple.callback();
System.out.println(simple.getClass().getName());
}
}
输出:
lambda callback...
com.ch.java8.lambda.Client$$Lambda$1/1490180672
匿名内部类和使用lambda表达式生成的类名有差异。
函数式接口
有且仅有一个抽象方法的普通接口。
Lambda表达式也是实现了接口的抽象方法,而且是接口中唯一的抽象方法,对于含有多个抽象方法的接口,就不能使用Lambda表达式了。
要将一个接口声明为函数式接口,需要在接口中加以下注解:
@FunctionalInterface
在JDK8中,内置了很多函数式接口,可以方便我们直接使用。
详见包路径:java.util.function。
常用的接口
-
Supplier 生产者
无参数,返回结果。 -
Consumer 消费者
接收一个入参,不返回结果。 -
Function 普通函数
接收一个入参,返回结果。 -
Predicate 断言
接收一个入参,返回布尔值。
Java8提供这些函数式接口,就是为了我们使用Lambda表达式的时候方便,无需自己再去单独定义函数式接口。
接口的默认、静态方法
JDK8之前,接口中只能定义抽象方法,如果接口新增方法,需要修改所有的实现类。
静态方法也只能写在类中,不能定义在接口中。
JDK8中,接口可以有默认方法、静态方法。
/**
* @Description: 简单接口
*/
@FunctionalInterface
public interface Simple {
void callback();
//默认方法
default void defaultFun(){
System.out.println("default function...");
}
//静态方法
static void staticFun(){
System.out.println("static function...");
}
}
/**
* @Description: 客户端测试
*/
public class Client {
public static void main(String[] args) {
Simple simple = () -> System.out.println("lambda callback...");
simple.defaultFun();
Simple.staticFun();
}
}
输出:
default function...
static function...
默认方法通过实例调用,子类可以选择覆盖默认方法。
静态方法通过类调用。
方法引用
自己不实现具体的方法,让JVM引用其他的方法。
/**
* @Description: 方法引用
*/
public class FunQuote {
public static void main(String[] args) {
Consumer<String> consumer = (s) -> System.out.println(s);
consumer.accept("admin");
//方法引用
consumer = System.out::println;
consumer.accept("Lisa");
}
}
输出:
admin
Lisa
被引用的方法必须与函数式接口中的抽象方法:返回值和形参列表一致。
静态引用
类名::静态方法名
/**
* @Description: 静态引用
*/
public class FunQuote {
public static void main(String[] args) {
//静态引用
Consumer<String> consumer = FunQuote::staticQuote;
consumer.accept("admin");
}
public static void staticQuote(String s){
System.out.println("静态引用:" + s);
}
}
输出:
静态引用:admin
实例引用
对象::实例方法名
/**
* @Description: 对象::实例方法引用
*/
public class FunQuote {
public static void main(String[] args) {
//对象::实例方法引用
Consumer<String> consumer = new FunQuote()::quote;
consumer.accept("admin");
}
public void quote(String s){
System.out.println("对象引用:" + s);
}
}
输出:
对象引用:admin
类名::实例方法名
/**
* @Description: 类名::实例方法引用
*/
public class FunQuote {
public static void main(String[] args) {
//类名::实例方法引用
Function<String, String> function = String::toUpperCase;
String apply = function.apply("admin");
System.out.println(apply);
}
}
输出:
ADMIN
引用构造器
/**
* @Description: 引用构造器
*/
@Data
public class ConstructorQuote {
private String name;
public ConstructorQuote(String name){
this.name = name;
}
public static void main(String[] args) {
Function<String, ConstructorQuote> function = ConstructorQuote::new;
ConstructorQuote quote = function.apply("admin");
System.out.println(quote.name);
}
}
输出:admin
引用数组
/**
* @Description: 数组引用
*/
public class ArrayQuote {
public static void main(String[] args) {
Function<Integer,String[]> function = String[]::new;
String[] apply = function.apply(10);
System.out.println(apply.length);
}
}
输出:10