阅读建议
嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议:
- 本篇文章大概000多字,预计阅读时间长需要5分钟。
- 本篇文章的实战性、理论性较强,是一篇质量分数较高的技术干货文章,建议收藏起来,方便时常学习与回顾,温故而知新。
- 创作不易,免费的点赞、关注,请走上一走,算是对博主一些鼓励,让我更有动力输出更多的干货内容。
了解lambda表达式
Java 8中的Lambda表达式是一种匿名函数,它允许你将函数作为方法参数进行传递,或者把代码更简洁地定义在你的应用程序里。另外Java的函数式编程就是Lambda表达式,java的函数式接口的有一个明显特征:有且仅有一个抽象方法的接口。
语法
标准语法
Lambda表达式的语法基本形式如下:
(parameters) -> expression
Lambda表达式在Java语言中引入了一个操作符“->”,该操作符被称为Lambda操作符或箭头操作符。它将Lambda分为两个部分:
- 左侧:指定了Lambda表达式需要的所有参数
- 右侧:制定了Lambda体,即Lambda表达式要执行的功能。
简写语法
语法格式一:无参,无返回值,Lambda体只需一条语句。如下:
@Test
public void test01(){
Runnable runnable=()-> System.out.println("hello world");
runnable.run();//结果:hello world
}
语法格式二:Lambda需要一个参数,无返回值。如下:
@Test
public void test02(){
Consumer<String> consumer=(x)-> System.out.println(x);
consumer.accept("Hello world");//结果:Hello world
}
语法格式三:Lambda只需要一个参数时,参数的小括号可以省略,如下:
public void test03(){
Consumer<String> consumer=x-> System.out.println(x);
consumer.accept("Hello world");//结果:Hello world
}
语法格式四:Lambda需要两个参数,并且Lambda体中有多条语句。
@Test
public void test04(){
Comparator<Integer> com=(x, y)->{
System.out.println("Hello world");
return Integer.compare(x,y);
};
System.out.println(com.compare(2,4));//结果:-1
}
语法格式五:有两个以上参数,有返回值,若Lambda体中只有一条语句,return和大括号都可以省略不写
@Test
public void test05(){
Comparator<Integer> com=(x, y)-> Integer.compare(x,y);
System.out.println(com.compare(4,2));//结果:1
}
语法格式六:Lambda表达式的参数列表的数据类型可以省略不写,因为JVM可以通过上下文推断出数据类型,即“类型推断”
@Test
public void test06(){
Comparator<Integer> com=(Integer x, Integer y)-> Integer.compare(x,y);
System.out.println(com.compare(4,2));//结果:1
}
方法的引用
使用方法引用的前提
- 方法引用所引用的方法的参数列表必须要和函数式接口中抽象方法的参数列表相同(完全一致)。
- 方法引用所引用的方法的的返回值必须要和函数式接口中抽象方法的返回值相同(完全一致)。
方法引用一般有三种格式
- 调用构造方法:调用类的构造方法,使用lambda表达工可以简写为:类名::new,这里需要注意的是函数式接口的参数类型、返回值类型要与所引用的方法保持一致
@FunctionalInterface
public interface MyFunction<R> {
R execute();
}
@FunctionalInterface
public interface MyFunction2<T,R> {
R execute(T T);
}
@Test
public void test07() {
//无参数的构造方法
MyFunction<Student> myFunction=Student::new;
Student student = myFunction.execute();
//有参数的构造方法
MyFunction2<String,Student> myFunction2=Student::new;
student = myFunction2.execute("zhangsan");
}
- 调用静态方法:调用类的静态方法,使用lambda表达工可以简写为:类名::静态方法名,这里需要注意的是函数式接口的参数类型、返回值类型要与所引用的方法保持一致
@FunctionalInterface
public interface MyFunction {
void execute();
}
@FunctionalInterface
public interface MyFunction2<T, R> {
R execute(T T);
}
@Test
public void test07() {
MyFunction myFunction = Student::play;//play()是无参数无返回值静态方法
MyFunction2<String, String> myFunction2 = Student::show;//有参数有返回值的静态方法
}
- 调用实例方法:调用类的实例方法有两种写法,第一种:对象类::实例方法名;第二种:类名::实例方法名;两种方法的区别在于函数式接口的参数类型不同,如果是类名::实例方法名,表达式表面上没有传参数,实际上是要接收一个实例对象作为参数的;
@FunctionalInterface
public interface MyFunction<R> {
R execute();
}
@FunctionalInterface
public interface MyFunction2<T, R> {
R execute(T T);
}
@Test
public void test07() {
Student student = new Student("张三");
MyFunction<String> myFunction = student::getName;
String name = myFunction.execute();
MyFunction2<Student, String> myFunction2 = Student::getName;
name = myFunction2.execute(student);
}
自定义函数式接口
自定义函数接口很容易,只需要编写一个只有一个抽象方法的接口即可。代码中的@FunctionalInterface是可选的,但加上该标注编译器会帮你检查接口是否符合函数接口规范。就像加入@Override标注会检查是否重载了函数一样。
@FunctionalInterface
public interface MyFunction2<T, R> {
R execute(T T);
}
应用场景
Java的Lambda表达式是一种简洁的函数式编程语法,它允许将简单的函数作为一种数据类型传递,是Java语言向函数式编程迈进的重要一步。在实际的应用过程,有很多场景可以使用lambda表达式,如:
- 简化代码:Lambda表达式可以使代码更加简洁、易读和易于维护。通过使用Lambda表达式,可以将匿名内部类的代码简化为一个简洁的表达式。
- 流式编程:Java 8引入了流API,可以使用Lambda表达式对集合进行过滤、映射、排序等操作。Lambda表达式使得流式编程更加简洁和直观。
- 回调函数:Lambda表达式可以作为回调函数使用,例如在GUI应用程序中,可以使用Lambda表达式作为按钮点击事件的回调函数。
- 排序和比较:Lambda表达式可以用于定义对象的排序规则和比较方法。例如,可以使用Lambda表达式定义一个自定义的排序规则,按照某个属性进行排序。
- 函数式接口:Lambda表达式可以用于实现函数式接口,即只有一个抽象方法的接口。例如,可以使用Lambda表达式实现Comparator接口,以便对集合进行排序。
- 并发编程:Lambda表达式可以用于实现线程池中的任务。通过使用Lambda表达式,可以更方便地创建并发任务,而无需创建额外的类。
- 事件处理:在事件驱动的系统中,可以使用Lambda表达式作为事件处理程序。例如,在Web应用程序中,可以使用Lambda表达式处理HTTP请求或响应。
优点和缺点
Java 8的新特性Lambda表达式功能很强大,它为Java带来了函数式编程的特性。从不同的层面来看,有很多的优点,也存在一些缺点,这需要在使用的时候特别注意,以下仅供参考:
优点:
- 简洁:Lambda表达式可以极大地简化代码,尤其是对于一些简单的函数式编程任务。通过使用Lambda表达式,可以避免编写冗长且难以理解的匿名内部类。
- 可读性强:Lambda表达式通常更容易理解,尤其是对于那些熟悉函数式编程的开发者来说。通过使用Lambda表达式,可以将代码的意图更清晰地表达出来。
- 灵活性高:Lambda表达式提供了更大的灵活性,可以在运行时动态地改变代码的行为。这使得Lambda表达式非常适合于实现一些复杂的逻辑。
- 提高性能:Lambda表达式在某些情况下可以提高代码的性能。这是因为Lambda表达式可以避免创建不必要的对象,从而减少了垃圾回收的压力。
- 易于测试:由于Lambda表达式只是一个函数,因此可以更容易地对它们进行单元测试。
缺点:
- 学习曲线陡峭:对于那些不熟悉函数式编程的开发者来说,Lambda表达式可能需要一些时间来理解和学习。这可能需要他们在初期投入更多的时间和精力。
- 不适合所有情况:虽然Lambda表达式在某些情况下可以提高性能,但在其他情况下可能会降低性能。例如,如果Lambda表达式中包含了复杂的操作或者有大量的数据传递,那么使用Lambda表达式可能会比使用传统的循环或者方法调用更加耗时。
- 调试困难:当Lambda表达式出现问题时,调试可能会更加困难。这是因为Lambda表达式可能涉及到多个不同的函数和方法,而且可能难以确定问题的具体位置。
- 语法糖衣:Lambda表达式实际上是一种语法糖衣,它使得函数式编程更加易于理解,但在某些情况下可能会掩盖代码的真实意图。这可能会导致代码的可维护性和可读性降低。