Java 函数式编程:从Lambda到Stream API
函数式编程是一种将计算表示为数学函数求值的编程范式,避免状态变化和数据突变。长期以来,Java一直是一种严格的面向对象语言,但随着Java 8(2014年)的发布,它通过添加Lambda表达式、函数式接口和Stream API向函数式编程迈出了巨大的一步。如今,这些工具对于编写简洁、可读且线程安全的代码不可或缺。
在本文中,我们将解析Java中函数式编程的关键概念:从Lambda的基础知识到使用Stream API的高级集合处理。本材料面向已经熟悉Java基本语法但希望掌握现代方法的开发者。
1. Lambda表达式与函数式接口
Lambda表达式是一种匿名函数(没有名称的方法),可以作为参数传递或存储在变量中。在Java中,Lambda实现了一个函数式接口——一个恰好包含一个抽象方法的接口(SAM——单一抽象方法)。
语法:
(parameters) -> { body }示例:不再为比较器创建匿名类:
// 旧方式 (Java 7)Comparator<String> comparator = new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.length() - s2.length(); }};
// 新方式 (Java 8+)Comparator<String> comparatorLambda = (s1, s2) -> s1.length() - s2.length();Java中的主要函数式接口(包 java.util.function):
Predicate<T>— 检查条件(方法test)。Function<T, R>— 将类型T的对象转换为R(方法apply)。Consumer<T>— 对对象执行操作(方法accept)。Supplier<T>— 在没有输入参数的情况下提供对象(方法get)。
使用Predicate的示例:
Predicate<Integer> isEven = n -> n % 2 == 0;System.out.println(isEven.test(4)); // trueSystem.out.println(isEven.test(5)); // false方法引用是Lambda的一种简写形式,当Lambda体由单个方法调用组成时使用:
// Lambdalist.forEach(item -> System.out.println(item));// 方法引用list.forEach(System.out::println);2. Stream API:基本操作
Stream API是一个强大的工具,用于以声明式风格处理数据序列(集合、数组、文件)。Stream不存储数据;它只描述一个操作流水线。数据不会被修改——每一步都会创建一个新的流。
创建Stream:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");Stream<String> stream = names.stream(); // 串行Stream<String> parallelStream = names.parallelStream(); // 并行中间操作(返回一个新的Stream):
filter(Predicate)— 根据条件选择元素。map(Function)— 转换每个元素。sorted()/sorted(Comparator)— 排序。distinct()— 去除重复项。limit(n)— 限制元素数量。
终端操作(结束Stream,返回结果):
collect(Collectors.toList())— 收集到集合中。forEach(Con