Java 8 Lambda与Stream
2026/1/15大约 4 分钟JavaJava版本特性LambdaStreamJavaJava新特性Optional模块化虚拟线程
概述
Java 8(2014年3月)是继 Java 5 之后最重要的版本,引入了函数式编程特性,彻底改变了 Java 的编程风格。这是第一个 LTS(长期支持)版本。
Lambda 表达式
Lambda 表达式是匿名函数,可以作为参数传递。
基本语法
// 完整形式
(parameters) -> { statements; }
// 简化形式
(parameters) -> expression
// 示例
// 无参数
() -> System.out.println("Hello")
// 单参数(可省略括号)
x -> x * 2
// 多参数
(x, y) -> x + y
// 带类型声明
(int x, int y) -> x + y
// 多行语句
(x, y) -> {
int sum = x + y;
return sum;
}函数式接口
只有一个抽象方法的接口,可以用 Lambda 表达式实现。
@FunctionalInterface
public interface Calculator {
int calculate(int a, int b);
}
// 使用 Lambda
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;
System.out.println(add.calculate(2, 3)); // 5
System.out.println(multiply.calculate(2, 3)); // 6内置函数式接口
// Predicate<T> - 断言,返回 boolean
Predicate<String> isEmpty = s -> s.isEmpty();
Predicate<Integer> isPositive = n -> n > 0;
// Function<T, R> - 转换函数
Function<String, Integer> length = s -> s.length();
Function<Integer, String> toString = n -> String.valueOf(n);
// Consumer<T> - 消费者,无返回值
Consumer<String> printer = s -> System.out.println(s);
// Supplier<T> - 供应者,无参数
Supplier<Double> random = () -> Math.random();
// BiFunction<T, U, R> - 双参数函数
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;方法引用
方法引用是 Lambda 的简化写法。
// 静态方法引用
Function<String, Integer> parser = Integer::parseInt;
// 实例方法引用(特定对象)
String str = "Hello";
Supplier<Integer> lengthSupplier = str::length;
// 实例方法引用(任意对象)
Function<String, Integer> lengthFunc = String::length;
// 构造方法引用
Supplier<ArrayList<String>> listSupplier = ArrayList::new;
Function<Integer, int[]> arrayCreator = int[]::new;Stream API
Stream 是对集合的函数式操作,支持链式调用和并行处理。
创建 Stream
// 从集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream1 = list.stream();
// 从数组创建
String[] array = {"a", "b", "c"};
Stream<String> stream2 = Arrays.stream(array);
// 直接创建
Stream<String> stream3 = Stream.of("a", "b", "c");
// 无限流
Stream<Integer> infinite = Stream.iterate(0, n -> n + 1);
Stream<Double> randoms = Stream.generate(Math::random);中间操作
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// filter - 过滤
names.stream()
.filter(name -> name.length() > 3)
.forEach(System.out::println);
// map - 转换
names.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
// flatMap - 扁平化
List<List<Integer>> nested = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4)
);
nested.stream()
.flatMap(List::stream)
.forEach(System.out::println); // 1, 2, 3, 4
// sorted - 排序
names.stream()
.sorted()
.forEach(System.out::println);
// distinct - 去重
Stream.of(1, 2, 2, 3, 3, 3)
.distinct()
.forEach(System.out::println); // 1, 2, 3
// limit / skip
Stream.iterate(1, n -> n + 1)
.skip(5)
.limit(10)
.forEach(System.out::println); // 6-15终端操作
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// collect - 收集
List<Integer> evenList = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
// reduce - 归约
int sum = numbers.stream()
.reduce(0, Integer::sum);
Optional<Integer> max = numbers.stream()
.reduce(Integer::max);
// count
long count = numbers.stream()
.filter(n -> n > 2)
.count();
// anyMatch / allMatch / noneMatch
boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0);
boolean allPositive = numbers.stream().allMatch(n -> n > 0);
// findFirst / findAny
Optional<Integer> first = numbers.stream()
.filter(n -> n > 3)
.findFirst();Collectors 收集器
List<Person> people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 25)
);
// toList / toSet
List<String> names = people.stream()
.map(Person::getName)
.collect(Collectors.toList());
// toMap
Map<String, Integer> nameAgeMap = people.stream()
.collect(Collectors.toMap(Person::getName, Person::getAge));
// groupingBy - 分组
Map<Integer, List<Person>> byAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge));
// partitioningBy - 分区
Map<Boolean, List<Person>> partition = people.stream()
.collect(Collectors.partitioningBy(p -> p.getAge() > 25));
// joining - 拼接
String joined = people.stream()
.map(Person::getName)
.collect(Collectors.joining(", ")); // "Alice, Bob, Charlie"
// 统计
IntSummaryStatistics stats = people.stream()
.collect(Collectors.summarizingInt(Person::getAge));
System.out.println("Average: " + stats.getAverage());
System.out.println("Max: " + stats.getMax());Optional
用于处理可能为 null 的值,避免 NullPointerException。
// 创建
Optional<String> empty = Optional.empty();
Optional<String> of = Optional.of("Hello");
Optional<String> nullable = Optional.ofNullable(null);
// 判断和获取
if (optional.isPresent()) {
String value = optional.get();
}
// 更优雅的方式
optional.ifPresent(System.out::println);
// 默认值
String value = optional.orElse("default");
String value2 = optional.orElseGet(() -> "computed default");
String value3 = optional.orElseThrow(() -> new RuntimeException("Not found"));
// 转换和过滤
Optional<Integer> length = optional
.filter(s -> s.length() > 3)
.map(String::length);新的日期时间 API (java.time)
// LocalDate - 日期
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1990, 1, 15);
// LocalTime - 时间
LocalTime now = LocalTime.now();
LocalTime noon = LocalTime.of(12, 0);
// LocalDateTime - 日期时间
LocalDateTime dateTime = LocalDateTime.now();
// ZonedDateTime - 带时区
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
// 日期计算
LocalDate nextWeek = today.plusWeeks(1);
LocalDate lastMonth = today.minusMonths(1);
// 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dateTime.format(formatter);
LocalDateTime parsed = LocalDateTime.parse("2024-01-15 10:30:00", formatter);
// 时间间隔
Period period = Period.between(birthday, today);
Duration duration = Duration.between(startTime, endTime);接口默认方法和静态方法
public interface Vehicle {
// 抽象方法
void start();
// 默认方法
default void stop() {
System.out.println("Vehicle stopped");
}
// 静态方法
static Vehicle create() {
return new Car();
}
}总结
Java 8 核心特性:
| 特性 | 说明 |
|---|---|
| Lambda | 函数式编程,简化代码 |
| Stream | 集合的函数式操作 |
| Optional | 优雅处理 null |
| 新日期API | 不可变、线程安全的日期时间 |
| 接口默认方法 | 接口演进,向后兼容 |
| 方法引用 | Lambda 的简化写法 |
Java 8 是目前使用最广泛的 Java 版本之一,其函数式编程特性已成为现代 Java 开发的标准实践。
