目录
简介
基础语法
Lambda表达式的重要特征
使用Lambda表达式的优缺点
案例
案例1 无参无返回
案例2 有参有返回值
案例3 final类型参数
Java8内置的函数式接口
Function接口
Consumer接口
Predicate接口
Supplier接口
Lambda表达式(也称闭包)是Java 8中引入的一种新特性,被誉为是该版本最强大的新特性之一,它允许我们将函数作为参数传递给方法,或者将代码视为数据。Lambda表达式可以简化函数式接口的使用,使得代码更加简洁和灵活。
函数式接口是指只包含一个抽象方法的接口。使用Lambda表达式,我们可以将函数作为参数传递给这些接口的方法,从而避免了繁琐的匿名内部类的编写。
Lambda表达式的基本语法如下:
(parameters) -> expression
或者
(parameters) -> { statements; }
其中:
Lambda表达式的底层实现是以匿名内部类的形式实现的。通过使用Lambda表达式,可以将函数作为参数传递给其他方法,使代码更加简洁和灵活。这有助于提高代码的可读性和可维护性。
优点:
缺点:
public class Main {
public static void main(String[] args) {
// 使用Lambda表达式定义一个无参无返回值的匿名函数
Runnable runnable = () -> {
System.out.println("Hello, Lambda!");
};
// 在线程中使用Lambda表达式执行匿名函数
Thread thread = new Thread(runnable);
thread.start();
}
}
public class Main {
public static void main(String[] args) {
// 使用Lambda表达式定义一个有参有返回值的匿名函数
Calculator calculator = (int a, int b) -> {
return a + b;
};
// 调用Lambda表达式计算结果
int result = calculator.calculate(10, 5);
System.out.println(result); // 输出:15
}
// 函数式接口Calculator
interface Calculator {
int calculate(int a, int b);
}
}
public class Main {
public static void main(String[] args) {
// 使用Lambda表达式时,可以不显式声明参数类型,并且可以引用外部的final变量
final String prefix = "Hello, ";
Greeting greeting = (name) -> {
return prefix + name;
};
String message = greeting.greet("John");
System.out.println(message); // 输出:Hello, John
}
// 函数式接口Greeting
interface Greeting {
String greet(String name);
}
}
Java8提供了一个java.util.function包,包含了很多函数式接口,下面是其中的四个基本函数式接口:
Java 8 在 java.util.function 包下定义了很多标准函数式接口,主要分为以下几类:
接口 | 参数 | 返回值 | 类别 |
---|---|---|---|
Consumer | T | void | 消费型接口 |
Supplier | None | T | 供给型接口 |
Function | T | R | 函数型接口 |
Predicate | T | boolean | 断言型接口 |
Function
下面是代码案例,演示了使用Function接口的例子:
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// 使用Function接口将字符串转换为整数
Function stringToInteger = (str) -> Integer.parseInt(str);
int number = stringToInteger.apply("123");
System.out.println(number); // 输出:123
// 使用Function接口将整数加倍,并返回结果的字符串形式
Function doubleToString = (num) -> String.valueOf(num * 2);
String result = doubleToString.apply(5);
System.out.println(result); // 输出:10
}
}
在上面的代码中,我们首先定义了一个Function接口stringToInteger,用于将字符串转换为整数。然后,我们调用apply()方法传入一个字符串参数,它会执行Lambda表达式并返回转换后的整数。
接着,我们定义了另一个Function接口doubleToString,用于将整数加倍,并将结果转换为字符串。同样地,我们调用apply()方法传入一个整数参数,执行Lambda表达式并返回结果的字符串形式。
Consumer
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
// 使用Consumer接口打印字符串列表中的每个元素
List fruits = Arrays.asList("Apple", "Banana", "Orange");
Consumer printConsumer = (fruit) -> System.out.println(fruit);
fruits.forEach(printConsumer);
// 使用Consumer接口修改字符串列表中的每个元素为大写形式
List animals = Arrays.asList("cat", "dog", "elephant");
Consumer uppercaseConsumer = (animal) -> {
String uppercaseAnimal = animal.toUpperCase();
System.out.println(uppercaseAnimal);
};
animals.forEach(uppercaseConsumer);
}
}
在以上代码中,我们首先定义了一个Consumer接口printConsumer,用于打印字符串列表中的每个元素。我们使用forEach()方法遍历字符串列表,并在每次迭代时调用accept()方法执行Lambda表达式输出字符串。
接着,我们定义了另一个Consumer接口uppercaseConsumer,用于将字符串列表中的每个元素转换为大写形式并输出。我们在Lambda表达式中执行字符串的大写转换并输出大写结果。
Predicate
以下是一个使用Predicate接口的代码示例:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Main {
public static void main(String[] args) {
// 创建一个整数列表
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 使用Predicate接口过滤偶数
Predicate evenPredicate = (number) -> number % 2 == 0;
List evenNumbers = filterList(numbers, evenPredicate);
System.out.println("偶数: " + evenNumbers);
// 使用Predicate接口过滤大于5的数字
Predicate greaterThanFivePredicate = (number) -> number > 5;
List greaterThanFiveNumbers = filterList(numbers, greaterThanFivePredicate);
System.out.println("大于5的数字: " + greaterThanFiveNumbers);
}
private static List filterList(List list, Predicate predicate) {
List result = new ArrayList<>();
for (Integer number : list) {
if (predicate.test(number)) {
result.add(number);
}
}
return result;
}
}
在上面的代码中,我们首先创建了一个整数列表numbers,包含一组整数。然后,我们定义了两个不同的Predicate接口实例:
接下来,我们编写了一个名为filterList()的辅助方法,该方法接受一个整数列表和一个Predicate接口作为参数,并返回满足Predicate条件的所有元素所组成的列表。在main()方法中,我们分别使用evenPredicate和greaterThanFivePredicate来过滤numbers列表。然后,将过滤后的结果打印输出。
Supplier
以下是一个使用Supplier接口的Java代码示例:
import java.util.Random;
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) {
// 使用Supplier接口创建实例
Supplier randomValueProvider = () -> {
Random random = new Random();
int randomInt = random.nextInt(100);
System.out.println("生成随机数:" + randomInt);
return randomInt;
};
int randomValue1 = randomValueProvider.get();
System.out.println("第一次获取的随机数:" + randomValue1);
int randomValue2 = randomValueProvider.get();
System.out.println("第二次获取的随机数:" + randomValue2);
}
}
这些函数式接口可以简化代码,并更方便地进行函数式编程。除了上述四个基本接口外,还有其他常用的函数式接口,如BiFunction、UnaryOperator、BinaryOperator等。