【java基础】Lambda表达式
Lambda表达式介绍
Java支持Lambda 表达式始于Java 8,它的出现简化了函数式接口匿名内部类的语法。使用Lambda表达式可以让我们的代码更少,看上去更简洁,代码更加灵活。但也有它的缺点所在,如果Lambda表达式用的不好的话,调试运行和后期维护比较麻烦。
Lambda只能接受函数式接口,所谓的函数式接口指的是只能有一个抽象方法的接口。
Lambda表达式语法
Lambda表达式通过操作符->分为两个部分:
• 左侧:指定了Lambda表达式所需要的所有参数。
• 右侧:指定了Lambda体,即Lambda表达式所要执行的功能。
Lambda表达式的基本语法结构如下,当然,这里只是简单的Lambda 表达式的应用。
到目前为止,我们对Lambda表达式有了基本的认识,下面用几个简单的例子来让我们好好理解一下Lambda表达式的使用,看看Lambda是怎样简化了函数式接口匿名内部类的。
public class LambdaExample {
public static void main(String[] args) {
//普通写法(匿名内部类)
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Ordinary Writing");
}
});
thread.start();
//Lambda写法。无参无返回void
Thread thread1 = new Thread(() -> System.out.println("Lambda Writing"));
thread1.start();
}
}
******************【运行结果】******************
Ordinary Writing
Lambda Writing
函数式接口
前面讲了使用Lambda表达式的前提是函数式接口,所以接下来学习一下函数式接口。
函数式接口介绍
函数式接口的定义:只允许有一个抽象方法的接口,那么它就是一个函数式接口。针对函数式接口,官方给我们提供了一个注解@FunctionalInterface,该注解会检查它是否是一个函数式接口,所以如果我们需要自定义一个函数式接口的话,可以在接口类的上方声明@FunctionalInterface。
需要注意的是,数式接口虽然规定只能有一个抽象方法,但是同时可以有多个非抽象方法(如静态方法,默认方法,私有方法)。下面是一个自定义的函数式接口:
@FunctionalInterface
public interface FunctionalInterface {
/**
* 抽象方法(只能有一个)
*/
void method();
//void method1();再定义一个会提示:找到多个抽象方法
/**
* 默认方法,必须用default修饰
*/
default void defaultMethod() {
System.out.println("默认方法...");
}
/**
* 静态方法方法
*/
static void staticMethod() {
System.out.println("静态方法...");
}
}
四大类型接口
Java8中增加了一个包:java.util.function。它们里面包含了常用的函数式接口,该包下定义的函数式接口非常多,主要有四大类:
可以看出四种函数式接口抽象方法的特点如下:
• 消费型接口:有参数传入,无结果返回。
• 供给型接口:无参数传入,但是有返回值
• 判断型接口:有参传入,但是返回值类型是boolean结果。
• 功能型接口:既有参数传入又有结果值返回
四种函数式接口的用法简单举例如下:
/**
* 内置最常用的四种函数式接口
*/
class FunctionalnterfaceTest{
//消费型接口
public void test0(){
Consumer<String> consumer = s -> System.out.println("[Consumer<T>]--->" + s);
consumer.accept("hello");
}
//供给型接口
public void test1() {
Supplier<String> supplier = () -> "hello";
System.out.println("[Supplier<T>]--->" + supplier.get());
}
//判断型接口
public void test2() {
Predicate<String> predicate = s -> s.equals("hello");
System.out.println("[Predicate<T>]--->" + predicate.test("hello"));
}
//功能性接口
public void test3() {
Function<String, String> function = (s) -> {
return "hello" + s;
};
System.out.println("[Function<T, R>]--->" + function.apply("666"));
}
}
public class FunctionalnterfaceExample {
public static void main(String[] args) {
FunctionalnterfaceTest functionalnterfaceTest = new FunctionalnterfaceTest();
functionalnterfaceTest.test0();
functionalnterfaceTest.test1();
functionalnterfaceTest.test2();
functionalnterfaceTest.test3();
}
}
******************【运行结果】******************
[Consumer<T>]--->hello
[Supplier<T>]--->hello
[Predicate<T>]--->true
[Function<T, R>]--->hello666
其实,这四种函数式接口每种都有其变种形式,如消费型接口有如下几种形式:
不过尽管形式很多,但是用法其实和最基本的用法差不多,这里就不一一介绍了。
本文源码地址:
https://github.com/qinlizhong1/javaStudy/tree/master/javaExample/src/main/java/java8
本文示例代码环境:
操作系统:macOs 12.1
JDK版本:12.0.1
maven版本: 3.8.4
👆扫描上方二维码关注