Java 8 是 Java 发展史上的一个里程碑版本,它引入了许多革命性的新特性,极大地提升了 Java 语言的 expressive(表达能力)和 productivity(生产力),其中最核心、最重要的更新就是对 API 的增强。

核心新特性概述
Java 8 的 API 更新主要集中在以下几个方面,这些特性是相互关联、共同使用的:
- Lambda 表达式:引入了函数式编程的概念,允许将函数作为方法参数,使代码更简洁、更灵活。
- Stream API:提供了一种对集合进行声明式操作的新方式,可以链式调用各种操作(如过滤、排序、映射),以函数式的方式处理数据。
- 新的
java.util.stream包:这是 Stream API 的具体实现,包含了各种流式操作的类和方法。 - 新的
java.util.function包:定义了一系列函数式接口(如Function,Predicate,Consumer),是 Lambda 表达式和 Stream API 的基础。 - Optional 类:一个容器类,用于替代
null引用,从根源上解决NullPointerException的问题,鼓励更健壮的代码。 - 新的日期和时间 API (
java.time):彻底取代了有诸多问题的旧版java.util.Date和java.util.Calendar,提供了更清晰、更强大的日期时间处理工具。 - 接口的默认方法和静态方法:允许在接口中定义带有实现的方法,使得 API 的向后兼容性变得更容易。
核心新 API 详解
下面我们逐一深入讲解这些核心 API 的中文文档和使用方法。
Lambda 表达式
Lambda 表达式可以看作是匿名内部函数,它没有名称,但有参数列表、函数体、返回值,可能还有一个可以抛出的异常列表。
基本语法:
(parameters) -> { statements; }
中文解释:
parameters:参数列表,与普通方法的参数列表类似。->:箭头符号,分隔参数列表和函数体。{ statements; }:函数体,可以是一行或多行代码,如果只有一行代码,可以省略 和return关键字。
示例:
假设我们有一个 List<String>,想在 Java 7 和 Java 8 中分别对其进行排序。
Java 7 (匿名内部类):
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a); // 降序排序
}
});
Java 8 (Lambda 表达式):
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
// 参数类型可以省略,因为编译器可以推断出来
Collections.sort(names, (a, b) -> b.compareTo(a));
可以看到,Lambda 表达式让代码变得极其简洁。
Stream API
Stream API 是对集合(Collection)功能的增强,它提供了一种声明式(告诉你要做什么,而不是怎么做)的方式来处理数据集合。
中文核心概念:
- 创建流:可以从集合、数组等数据源创建流。
list.stream(): 创建一个顺序流。list.parallelStream(): 创建一个并行流(多线程处理)。
- 中间操作:返回一个新的流,可以进行链式调用,常见的有:
filter(Predicate<T>): 过滤流中的元素,保留满足条件的。map(Function<T, R>): 将流中的元素映射成另一种类型。sorted(): 对流进行排序。distinct(): 去重。
- 终端操作:关闭流,并产生最终结果,常见的有:
forEach(Consumer<T>): 遍历流中的每个元素。collect(Collectors.toList()): 将流中的元素收集到一个新的集合中。count(): 计算流中元素的数量。reduce(...): 将流中的元素组合成一个单一的结果。
示例: 从一个员工列表中,找出所有年龄大于 30 的员工,并提取出他们的姓名,最后按字母顺序排序。
List<Employee> employees = Arrays.asList(
new Employee("张三", 28),
new Employee("李四", 35),
new Employee("王五", 40),
new Employee("赵六", 30)
);
List<String> filteredNames = employees.stream()
// 1. 过滤:年龄大于 30
.filter(e -> e.getAge() > 30)
// 2. 映射:提取姓名
.map(Employee::getName)
// 3. 排序:按姓名字母顺序
.sorted()
// 4. 收集:将结果收集到 List 中
.collect(Collectors.toList());
// filteredNames 结果: ["李四", "王五"]
System.out.println(filteredNames);
Employee::getName 是方法引用,是 Lambda 的另一种简化写法。
java.util.function 包
这个包是 Java 8 函数式编程的基石,定义了核心的函数式接口。
| 接口名 | 功能描述 | 示例 Lambda |
|---|---|---|
Predicate<T> |
断言型接口,接收一个 T 类型参数,返回一个 boolean 结果。 |
e -> e.getAge() > 30 |
Function<T, R> |
函数型接口,接收一个 T 类型参数,返回一个 R 类型结果。 | e -> e.getName() |
Consumer<T> |
消费型接口,接收一个 T 类型参数,无返回值 (void)。 |
System.out::println |
Supplier<T> |
供给型接口,无参数,返回一个 T 类型结果。 | () -> new Random().nextInt() |
UnaryOperator<T> |
一元操作符,接收一个 T 类型参数,返回一个 T 类型结果。 | x -> x * x |
BinaryOperator<T> |
二元操作符,接收两个 T 类型参数,返回一个 T 类型结果。 | (a, b) -> a + b |
这些接口是 Stream API 中各种操作(如 filter, map, forEach)的参数类型。
java.util.Optional 类
Optional 是一个容器对象,它可以包含或者不包含非 null 的值,如果存在值,isPresent() 将返回 true,get() 将返回该值,目的是为了取代 null,避免 NullPointerException。
中文核心方法:
of(T value): 创建一个包含非 null 值的 Optional。ofNullable(T value): 创建一个可能包含 null 值的 Optional,value 为 null,则创建一个空的 Optional。isPresent(): 判断是否包含值。ifPresent(Consumer<T> consumer): 如果包含值,就执行 consumer 的操作。get(): 获取值,如果为空则抛出NoSuchElementException(不推荐直接使用)。orElse(T other): 如果为空,则返回 other 默认值。orElseGet(Supplier<? extends T> other): 如果为空,则调用 Supplier 生成默认值(惰性求值)。orElseThrow(Supplier<? extends X> exceptionSupplier): 如果为空,则抛出指定的异常。
示例: 安全地从一个可能为 null 的 Map 中获取值。
Map<String, String> map = new HashMap<>();
// map.put("key", "value");
// Java 7 方式
String value = map.get("key");
if (value != null) {
System.out.println(value.toUpperCase());
}
// Java 8 Optional 方式
Optional<String> optionalValue = Optional.ofNullable(map.get("key"));
optionalValue.ifPresent(v -> System.out.println(v.toUpperCase()));
// 或者提供一个默认值
String result = optionalValue.orElse("默认值");
System.out.println(result);
新的日期和时间 API (java.time)
Java 8 引入了全新的 java.time 包,解决了旧 API 的所有问题,是不可变且线程安全的。
核心类:
LocalDate: 表示日期(年-月-日),不包含时间。LocalTime: 表示时间(时-分-秒-纳秒),不包含日期。LocalDateTime: 表示日期和时间(年-月-日-时-分-秒-纳秒)。ZonedDateTime: 表示带有时区的日期和时间。DateTimeFormatter: 用于日期时间的格式化和解析。
示例:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
// 获取当前日期和时间
LocalDate today = LocalDate.now();
LocalDateTime now = LocalDateTime.now();
System.out.println("今天的日期: " + today); // 2025-10-27
System.out.println("现在的时间: " + now); // 2025-10-27T15:30:45.123
// 格式化日期
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
String formattedDateTime = now.format(formatter);
System.out.println("格式化后的时间: " + formattedDateTime); // 2025年10月27日 15:30:45
// 解析字符串
LocalDate parsedDate = LocalDate.parse("2025-01-01", DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println("解析后的日期: " + parsedDate); // 2025-01-01
如何查找 Java 8 中文 API 文档?
-
官方 Oracle 文档 (英文为主,但有中文翻译社区版)
- 访问 Oracle Java SE 8 Documentation。
- 在页面顶部选择 "简体中文" (Simplified Chinese)。
- 你可以在线阅读或下载为 HTML/CHM 格式,这是最权威的来源。
-
国内技术社区和博客
- CSDN、掘金、思否 等平台有大量关于 Java 8 新特性的中文教程和文章,搜索 "Java 8 Stream API"、"Java 8 Lambda" 等关键词可以找到非常详细的中文解释和示例。
-
IDE 内置文档
- 像 IntelliJ IDEA 和 Eclipse 这类现代 IDE 都可以很方便地查看 API 文档。
- IntelliJ IDEA: 按住
Ctrl鼠标悬停在类或方法上,会弹出文档,也可以使用Ctrl + Q快捷键。 - 这些文档通常是英文的,但配合中文教程学习效果更佳。
Java 8 的 API 更新是革命性的,掌握 Lambda、Stream、Optional 和 java.time 这些新特性,是成为一名现代 Java 开发者的必备技能,它们让代码更简洁、更易读、更健壮,并且充分利用了多核 CPU 的并行处理能力,建议您从上面的示例开始,亲手编写代码,逐步熟悉这些强大的新 API。
