一、使用Lambda表达式的好处。
1. 简化代码:lambda表达式可以将函数式接口的实现简化为几行代码,避免编写冗长的匿名内部类或单独定义函数的过程。它可以使代码更加简洁、易读、易于维护。
2. 增强代码可读性:lambda表达式可以更好地表达代码的意图,提高代码的可读性。通过使用lambda表达式,可以更清晰地描述函数式接口的行为,使代码逻辑更加直观明了。
3. 支持函数式编程:引入lambda表达式使Java能够更好地支持函数式编程范式。函数式编程强调将计算视为函数求值,并避免改变状态和可变数据。lambda表达式可以帮助开发人员更自然地编写函数式风格的代码。
4. 支持并行处理:lambda表达式可以与Java 8引入的Stream API结合使用,实现更方便的并行处理。使用lambda表达式可以更容易地编写并行化的代码,充分利用多核处理器的优势,提高性能。
5. 促进代码重用:lambda表达式可以作为参数传递给其他方法,可以在不改变原有代码结构的情况下轻松实现不同的行为。这种代码重用的能力使得代码更加灵活、可扩展。
二、Lambda表达式的基本使用
1、lambda表达式的基础语法:核心代表就是这个箭头操作符 “ -> ” ,而这个箭头操作符分成2部分。
第一部分:箭头操作符的左侧
表示参数列表,也就是需要定义的参数
第二部分:箭头操作符的右侧
表示需要执行的功能,也就是lambda体
例如 : public Boolean test(T t)
左侧 == 以上抽象方法的 (T t)参数类型,以及参数
右侧 == 以上抽象方法的 public Boolean test(T t) 方法体
2、Lambda表达式需要函数式接口
Lambda表达式需要 “函数式接口的支持“,那什么是函数式接口,函数式接口就是,接口中只有一个抽象方法的接口,称为函数式接口。在定义函数式接口的时候,可以使用一个注解,这个注解就是@FunctionInterface 这个注解表示这个接口只能存在一个抽象方法。当使用了这个注解之后,那么这个接口就是一个函数式接口,因为使用了该注解之后,该接口只能存在一个抽象方法。
Lambda表达式其实就是对接口的调用。
语法格式一:无参数 无返回值的抽象方法
使用方式 : () -> System.out.println("内容");
/**
* 语法格式 1 : 无参数 无返回值的方法
* () -> System.out.println("");
*/
@Test
public void t1() {
// 传统的
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("你好");
}
};
r.run();
System.out.println("==================");
// 使用lambda表达式
Runnable r2 = () -> System.out.println("你好2");
r2.run();
}
语法格式二:有一个参数,并且无返回值的抽象方法
使用方式 : (参数变量) -> System.out.println("内容");
/**
* 语法格式2 : 有一个参数,并且无返回值的接口方法
* (参数值) -> System.out.println("");
*/
@Test
public void test02() {
Consumer<String> consumer = (x) -> System.out.println(x);
consumer.accept("你好");
}
语法格式三:若只存在一个参数,并且无返回值,箭头左侧的小括号可以省略不写
使用方式 :参数变量 -> System.out.println("内容"); 或者 System.out::println;
/**
* 语法格式3 :若只有一个参数,并且没有返回值 , 小括号可以直接不写
* x -> System.out.println("");
* System.out::println;
*/
@Test
public void test03() {
Consumer<String> consumer = System.out::println;
consumer.accept("你好");
Consumer<String> consumer1 = x -> System.out.println(x);
consumer1.accept("你好2");
}
语法格式四:有两个或者两个以上的参数,并且有返回值,而且Lambda体中有多条语句,那么Lambda体中必须使用大括号 "{}"
使用方式 : (x,y,...) -> {
System.out.println("内容");
return Integer.copare(x,y);
};
/**
* 语法格式4 : 有俩个或者两个以上的参数,并且有返回值,而且Lambda体中有多条语句(必须使用大括号{})
* (x,y,...) -> {
* System.out.println("");
* return Integer.compare(x, y);
* }
*/
@Test
public void test04() {
Comparator<Integer> comparator = (x, y) -> {
System.out.println("函数式接口");
return Integer.compare(x, y);
};
}
语法格式五:有两个或者两个以上的参数,并且有返回值,而且Lambda体中只有一条语句,就可以省略大括号
使用方式 : (x, y,...) -> Integer.compare(x, y);
/**
* 语法格式5 : 有俩个或者两个以上的参数,并且返回值,而且Lambda体中只有一条语句 就可以省略大括号
* (x,y,...) -> (x, y) -> Integer.compare(x, y);
*/
@Test
public void test05() {
Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
}
语法格式六:Lambda表达式的参数列表的数据类型可以不写,因为JVM编译器可以通过上下文推断出数据类型。
怎么通过上下文推断呢,拿以下接口说 , 例如 Comparator<T> 尖括号里面的T代表泛型,那么我在里面定义一个Integer的数据类型,那么上文就是Integer的数据类型,JVM就会自动的推断下文的数据类型。这个行为也被称为 “类型推断”。
/**
* 语法格式6 : Lambda表达式的参数列表的数据类型可以省略不写 ,因为JVM的编译器可以通过上下文推断出数据类型 ,但是你只要写了
* 那么就需要都写上 不然编译不通过
* (Integer x, Integer y) -> Integer.compare(x, y);
* 为什么可以推断出来 因为你在这个comparator中已经定义了Integer的数据类型
* 那么JVM会根据这个去推断lambda中的参数类型 通过上下文进行类型推断
*/
@Test
public void test06() {
Comparator<Integer> comparator = (Integer x, Integer y) -> Integer.compare(x, y);
Comparator<Integer> comparator2 = (x, y) -> Integer.compare(x, y);
}
总的来说,lambda表达式在Java中的使用可以简化代码、增强可读性、支持函数式编程、促进代码重用,并有助于提高并行处理性能。