概述
Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。
Lambda 表达式 − Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)
更多的新特性可以参阅官网:What's New in JDK 8
Lambda表达式
lambda表达式的语法由参数列表、->和函数体组成。函数体既可以是一个表达式,也可以是一个语句块:
表达式:表达式会被执行然后返回执行结果。
语句块:语句块中的语句会被依次执行,就像方法中的语句一样——
return语句会把控制权交给匿名方法的调用者
break和continue只能在循环中使用
如果函数体有返回值,那么函数体内部的每一条路径都必须返回值
表达式函数体适合小型lambda表达式,它消除了return关键字,使得语法更加简洁。
简单实现:
场景: 有一组员工数据,需要根据年龄、工资等不同的过滤条件,进行数据过滤。
基础实现:编写不同的过滤方法,按照各自的条件进行过滤,返回数据。
缺陷:冗余代码过多,只是条件不同,其余基本一致。
优化:使用策略模式,定义接口,按照条件实现不同的接口,使用时传入不同的接口即可,使用lambda更为简便。
定义的接口,声明为泛型
/*
* describe 接口,方便过滤,声明为一个泛型
*/
public interface MyPredicate<T> {
boolean test(T t);
}
按条件实现接口(根据不同的条件实现多个类,也可以使用匿名内部类)
/*
自定义按员工年龄过滤
*/
public class FilterEmployeeByAge implements MyPredicate<Employee> {
@Override
public boolean test(Employee employee) {
return employee.getAge() > 35;
}
}
使用接口来实现过滤
// 如果按不同的条件过滤,会产生冗余代码
// 优化方式1:
@Test
public void test4() {
// 添加条件,只需要实现MyPredicate接口,添加到此处即可
// List<Employee> list = filterEmployees(employees, new FilterEmployeeByAge());
List<Employee> list = filterEmployees(employees, new FilterEmployeeBySalary());
for (Employee item: list) {
System.out.println(item);
}
}
// 此时使用接口来操作
public List<Employee> filterEmployees(List<Employee> list, MyPredicate<Employee> mp){
List<Employee> emps = new ArrayList<>();
for (Employee item: list) {
if(mp.test(item)) {
emps.add(item);
}
}
return emps;
}
// 优化方式2:匿名内部类
@Test
public void test5() {
List<Employee> list = filterEmployees(employees, new MyPredicate<Employee>() {
// 匿名内部类 实现过滤条件
@Override
public boolean test(Employee employee) {
return employee.getSalary() < 5000;
}
});
for (Employee item:list) {
System.out.println(item);
}
}
// 优化方式3:Lambda 表达式实现(依赖接口及以上的过滤方法)
@Test
public void test6() {
List<Employee> list = filterEmployees(employees, (e) -> e.getSalary() < 5000);
list.forEach(System.out::println);
}
// 优化方式4:Lambda 配合stream实现(不依赖接口)
@Test
public void test7() {
// 转换为stream,配合filter实现过滤
employees.stream()
.filter((e) -> e.getSalary() < 5000)
.limit(2)
.forEach(System.out::println);
System.out.println("------------------------------------");
// 过滤后提取姓名
employees.stream()
.filter(e -> e.getSalary() < 5000)
.map(Employee::getName)
.forEach(System.out::println);
}
语法介绍:
/** * 一、lambda 表达式的基础语法: Java8中引入了一个新的操作符‘->’,箭头操作符或Lambda操作符 * 箭头操作符把表达式分为两部分 * 左侧:Lambda 表达式的参数列表 * 右侧:Lambda 表达式中所需执行的功能,Lambda体 * * 语法格式一:无参数、无返回值 * () -> System.out.println("Hello Lambda!") * * 语法格式二:有一个参数,无返回值 * (x) -> System.out.println(x); * * 语法格式三:有一个参数,无返回值,小括号可以省略 * x -> System.out.println(x); * * 语法格式四:有两个及以上参数,有返回值,并且lambda体中有多条语句 * (x,y) -> {...} * Comparator<Integer> comparator = (x, y) -> { * System.out.println("函数式接口"); * return Integer.compare(x, y); * }; * * 语法格式五:有两个及以上参数,有返回值,并且lambda体中只有一条语句,return、大括号可以省略 * (x, y) -> Integer.compare(x, y); * * 语法格式六:Lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出对应数据类型(类型推断) * (Integer x, Integer y) -> Integer.compare(x, y); * (x, y) -> Integer.compare(x, y); * * 二、Lambda 表达式需要函数式接口的支持 * 函数式接口:接口中只有一个抽象方法的接口。 可以使用注解 @FunctionalInterface 修饰 [ 检测是否是函数式接口 ] * */
测试程序,基本都添加了注释:
public class LambdaBase {
// 语法格式一:无参数、无返回值
@Test
public void test1() {
int num = 0; // jdk1.7之前需要声明为final,1,8无需声明,默认为final
// 匿名内部类实现
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello World" + num);
}
};
r.run();
System.out.println("------------------------");
// Lambda实现
Runnable lr = () -> System.out.println("Hello Lambda" + num);
lr.run();
}
// 语法格式二:有一个参数,无返回值
@Test
public void test2() {
// lambda右侧就是对Consumer中accept方法的实现
Consumer<String> consumer = (x) -> System.out.println(x);
consumer.accept("Lambda语法二,一个参数,无返回值");
}
// 语法格式三:有一个参数,小括号可以省略
@Test
public void test3() {
Consumer<String> consumer = x -> System.out.println(x);
consumer.accept("语法格式三:有一个参数,小括号可以省略");
}
// 语法格式四:有多个参数,Lambda中有多条语句,有返回值
@Test
public void test4() {
Comparator<Integer> comparator = (x, y) -> {
System.out.println("函数式接口");
return Integer.compare(x, y);
};
System.out.println(comparator.compare(4, 5));
}
// 语法格式五:有两个及以上参数,有返回值,并且lambda体中只有一条语句,return、大括号可以省略
@Test
public void test5() {
Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
System.out.println(comparator.compare(5,4));
}
/*********************************************************************************/
@Test
public void test6() {
// lambda表达式实现函数式接口
int result = operation(10, (x) -> x + x);
System.out.println(result);
System.out.println(operation(200, x -> x * x));
}
// 调用函数式接口进行计算
public Integer operation(Integer num, MyFunction<Integer> myFunction) {
return myFunction.getValue(num);
}
}
test6中函数式接口:
待续。
参考:
尚硅谷_Java8新特性
最后
以上就是快乐奇异果为你收集整理的Java 8系列之Lambda表达式(一)Lambda表达式的全部内容,希望文章能够帮你解决Java 8系列之Lambda表达式(一)Lambda表达式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复