鲲鹏社区首页
中文
注册
Java函数式编程

Java函数式编程

java

发表于 2025/04/23

0

Java Lambda 表达式与函数式编程

Lambda 表达式是 Java 8 引入的一个重要特性,它使得 Java 能够支持更简洁的函数式编程风格。Lambda 表达式的引入主要是为了简化代码,尤其是在处理集合、事件监听器和回调函数时,让代码更加简洁和易于理解。

1. Lambda 表达式的基本语法

Lambda 表达式的一般语法形式如下:

(parameters) -> expression
  • parameters:表示输入参数,可以有一个或多个。
  • ->:Lambda 操作符,用于将参数与表达式分开。
  • expression:表示 Lambda 表达式的主体部分,可以是一个简单的表达式或一个代码块。

2. Lambda 表达式的示例

  • 无参数的 Lambda 表达式
Runnable r = () -> System.out.println("Hello, Lambda!");
r.run(); // 输出: Hello, Lambda!
  • 单一参数的 Lambda 表达式

// 使用一个参数并返回该参数的平方
Function<Integer, Integer> square = x -> x * x;
System.out.println(square.apply(5)); // 输出: 25
  • 多个参数的 Lambda 表达式

// 使用两个参数并返回它们的和
BiFunction<Integer, Integer, Integer> sum = (a, b) -> a + b;
System.out.println(sum.apply(3, 4)); // 输出: 7
  • 带有代码块的 Lambda 表达式
// 计算两个数的和,并打印
BiFunction<Integer, Integer, Integer> sumAndPrint = (a, b) -> {
    System.out.println("Adding " + a + " and " + b);
    return a + b;
};
System.out.println(sumAndPrint.apply(3, 4)); // 输出: Adding 3 and 4
// 输出: 7

3. 函数式接口

Lambda 表达式通常与函数式接口一起使用。函数式接口是一个只包含一个抽象方法的接口。

  • 示例 1Runnable 接口
Runnable r = () -> System.out.println("Hello, World!");
new Thread(r).start();
  • 示例 2: 自定义函数式接口
@FunctionalInterface
interface MyFunction {
    int apply(int x, int y);
}
 
public class LambdaExample {
    public static void main(String[] args) {
        MyFunction sum = (a, b) -> a + b;
        System.out.println(sum.apply(10, 20)); // 输出: 30
    }
}

4. 常用函数式接口

Java 8 提供了一些常用的函数式接口,这些接口已经定义在 java.util.function 包中:

  • Predicate<T>:表示一个接受 T 类型参数并返回 boolean 的函数。
  • Function<T, R>:表示一个接受 T 类型参数并返回 R 类型结果的函数。
  • Consumer<T>:表示一个接受 T 类型参数并没有返回值的函数。
  • Supplier<T>:表示一个没有输入参数并返回 T 类型结果的函数。
  • BiFunction<T, U, R>:表示一个接受 T 和 U 类型参数并返回 R 类型结果的函数。

5. Lambda 表达式的应用案例

  • 集合遍历与过滤

使用 Lambda 表达式简化集合遍历和过滤操作:

List<String> names = Arrays.asList("John", "Jane", "Jack", "Mike", "Tom");
 
names.stream()
     .filter(name -> name.startsWith("J"))
     .forEach(System.out::println); // 输出: John, Jane, Jack
  • 排序操作

Lambda 表达式可以简化排序操作:

List<String> names = Arrays.asList("John", "Jane", "Jack", "Mike", "Tom");
 
names.sort((s1, s2) -> s1.compareTo(s2)); // 升序排序
names.forEach(System.out::println);
  • 映射与转换

使用 map() 函数来进行集合元素的转换:

List<String> names = Arrays.asList("John", "Jane", "Jack");
 
List<String> upperCaseNames = names.stream()
                                   .map(String::toUpperCase)
                                   .collect(Collectors.toList());
System.out.println(upperCaseNames); // 输出: [JOHN, JANE, JACK]
  • 收集与分组

使用 Collectors 类来收集数据并进行分组:

List<Person> people = Arrays.asList(
    new Person("John", 25),
    new Person("Jane", 30),
    new Person("Tom", 25)
);
 
Map<Integer, List<Person>> groupedByAge = people.stream()
    .collect(Collectors.groupingBy(Person::getAge));
 
groupedByAge.forEach((age, p) -> {
    System.out.println("Age: " + age);
    p.forEach(person -> System.out.println(person.getName()));
});

6. 函数式编程的特点与优势

  • 简洁性:Lambda 表达式让代码变得更简洁,减少了冗余代码。
  • 可读性:通过移除匿名内部类,提高了代码的可读性。
  • 惰性计算:Lambda 表达式结合 Stream API 允许惰性计算,可以优化性能。
  • 并行处理:通过 Stream API,可以轻松地将代码转换为并行计算模式。

7. 函数式编程的高级应用

  • 高阶函数:可以将函数作为参数传递或返回。
// 高阶函数:将函数作为参数
public static void printFiltered(List<String> list, Predicate<String> condition) {
    list.stream().filter(condition).forEach(System.out::println);
}
 
printFiltered(names, name -> name.startsWith("J"));
  • 组合函数:可以使用 andThen() 或 compose() 方法将多个函数组合在一起。
Function<Integer, Integer> multiplyBy2 = x -> x * 2;
Function<Integer, Integer> add3 = x -> x + 3;
 
Function<Integer, Integer> combined = multiplyBy2.andThen(add3);
System.out.println(combined.apply(5)); // 输出: 13 (5*2 + 3)
  • 不可变性:函数式编程强调使用不可变对象,避免副作用。
// 使用 Java 8 Immutable Collections
List<String> immutableList = List.of("a", "b", "c");

总结

Java 中的 Lambda 表达式和函数式编程给我们提供了更简洁、更易读的代码写法。通过结合 Stream API,Lambda 使得集合处理变得更加灵活,能够在实现并行计算、函数式变换和高阶函数等方面发挥巨大作用。

本页内容