在了解Lambda之前,我们先回顾一下Java的方法,帮助我们更好地理解函数式编程在Java中的应用。
1. Java的方法概述
在Java中,方法可以分为两大类:实例方法和静态方法。
1.1 实例方法
实例方法是绑定到类的某个实例上的方法,需要通过实例对象来调用。例如,Integer类的equals()方法:
javapublic final class Integer {boolean equals(Object o) {// 实现逻辑}}
此方法的调用需要通过对象来调用,并隐式传入当前对象的引用(即this)。
1.2 静态方法
静态方法属于类本身,不需要通过对象来调用。例如,Integer类的parseInt()方法:
javapublic final class Integer {public static int parseInt(String s) {// 实现逻辑}}
静态方法直接通过类名调用,不涉及this参数。
无论是实例方法还是静态方法,本质上都可以看作过程式语言中的函数,只是Java的实例方法隐式地传入了this,即方法的第一个参数是当前对象本身。
2. 什么是函数式编程?
函数式编程(Functional Programming,简称FP)是将函数作为基本运算单元的一种编程范式。在函数式编程中,函数不仅可以作为变量,还可以作为参数传递,也可以作为返回值返回。这种思想来源于Lambda演算(Lambda Calculus),因此很多支持此编程风格的语言(如Java 8及之后的版本)都提供了Lambda表达式。
3. Lambda表达式
3.1 Lambda表达式的简化
在Java中,Lambda表达式允许我们以一种更加简洁的方式传递行为。它可以简化传统匿名内部类的写法。
举个例子,Comparator接口是一个典型的单方法接口。在排序操作中,我们通常会用到这个接口。以下是使用匿名类实现排序的代码:
javaString[] array = {"Apple", "Orange", "Banana", "Lemon"};Arrays.sort(array, new Comparator<String>() {public int compare(String s1, String s2) {return s1.compareTo(s2);}});System.out.println(String.join(", ", array));
这段代码看起来很繁琐,特别是Comparator接口的实现部分。使用Lambda表达式,我们可以将代码简化为:
javaimport java.util.Arrays;public class Main {public static void main(String[] args) {String[] array = {"Apple", "Orange", "Banana", "Lemon"};Arrays.sort(array, (s1, s2) -> s1.compareTo(s2));System.out.println(String.join(", ", array));}}
在这段Lambda表达式中:
-
(s1, s2)是输入参数,类型可以省略,编译器会自动推断类型。 -
->表示Lambda表达式的主体,后面的部分是方法体。 -
在此例中,Lambda表达式中只有一行
return语句,因此可以进一步简化。
3.2 Lambda表达式的语法
Lambda表达式的基本语法如下:
java(parameters) -> expression
当Lambda表达式有多个参数时,我们需要用括号将其包裹。如果只有一个参数,可以省略括号。如果方法体包含多行代码,代码块需要用花括号包裹,且必须使用return语句返回值。
4. 功能接口(FunctionalInterface)
4.1 什么是功能接口?
在Java中,**功能接口(FunctionalInterface)**是指只包含一个抽象方法的接口。这样的接口非常适合用来作为Lambda表达式的目标类型。
我们可以使用@FunctionalInterface注解来显式声明接口为功能接口。以下是一个典型的功能接口示例:
java@FunctionalInterfacepublic interface Callable<V> {V call() throws Exception;}
4.2 Comparator接口示例
Comparator接口虽然包含多个方法,但它仍然是一个功能接口。因为它只定义了一个抽象方法:compare(),其他方法要么是default方法,要么是static方法。例如:
java@FunctionalInterfacepublic interface Comparator<T> {int compare(T o1, T o2);boolean equals(Object obj); // Object类的方法default Comparator<T> reversed() {return Collections.reverseOrder(this);}default Comparator<T> thenComparing(Comparator<? super T> other) { ... }}
在上面的代码中,Comparator只有一个抽象方法compare(),因此它符合功能接口的定义。
5. Lambda表达式练习
5.1 练习题:使用Lambda表达式实现忽略大小写排序
编写一个程序,使用Lambda表达式对字符串数组进行排序,要求排序时忽略大小写。
javaString[] array = {"Apple", "orange", "banana", "Lemon"};Arrays.sort(array, (s1, s2) -> s1.compareToIgnoreCase(s2));System.out.println(String.join(", ", array));
6. 小结
-
功能接口:只定义了一个抽象方法的接口被称为功能接口,可以通过
@FunctionalInterface注解进行标记。 -
Lambda表达式:可以用Lambda表达式简化匿名类的写法,使代码更加简洁和易读。
-
编译器自动推断:Lambda表达式的参数类型和返回值类型可以由编译器自动推断,极大地减少了代码冗余。
-
Lambda表达式的应用:Lambda表达式常用于处理单方法接口,特别是在集合框架(如
Comparator)的排序操作中。
通过以上内容,我们掌握了Lambda表达式的基本使用,并通过具体实例理解了它如何简化代码,提高代码可读性。
610

被折叠的 条评论
为什么被折叠?



