Java 8 是 Java 发展历程中的一个里程碑式版本,它引入了大量令人激动的新特性,极大地提升了开发效率。
Java 8 核心新特性
Java 8 最重要的特性主要围绕着 函数式编程 和 更高效的 API 设计。
1. Lambda 表达式 (Lambda Expressions)
这是 Java 8 最核心的特性之一,它允许你以更简洁的方式表示只有一个抽象方法的接口(即 函数式接口)的实例。
语法:
(parameters) -> expression
或(parameters) -> { statements; }
作用: 极大地简化了匿名内部类的使用,使得代码更加紧凑和易读,特别是在处理集合和事件时。
1 | //Java 7 或之前 |
2. 函数式接口 (Functional Interfaces)
Lambda 表达式的出现,使得 Java 需要一种新的方式来表示可以作为参数传递的代码块。函数式接口就是只有一个抽象方法的接口,它们是 Lambda 表达式的类型。
@FunctionalInterface
注解: 用于强制编译器检查该接口是否符合函数式接口的定义,如果不是,则会报错。Java 8 内置的函数式接口:
Consumer<T>
: 接收一个输入参数但不返回任何结果。Predicate<T>
: 接收一个输入参数,返回一个布尔值。Function<T, R>
: 接收一个输入参数,返回一个结果。Supplier<T>
: 不接收任何参数,返回一个结果。UnaryOperator<T>
: 接收一个输入参数,返回一个相同类型的结果(Function<T, T>
的特化)。BinaryOperator<T>
: 接收两个相同类型的输入参数,返回一个相同类型的结果(BiFunction<T, T, T>
的特化)。
3. Stream API
Stream API 是 Java 8 中处理集合(以及数组、I/O 渠道等)数据的新方式,它提供了一种声明式、函数式的数据处理能力。Stream API 可以将复杂的集合操作(如过滤、映射、查找、排序等)连接起来形成一个管道,从而实现高效的链式操作。
- 特性:
- 非破坏性: Stream 不会改变源数据结构。
- 惰性执行: 只有当终端操作被调用时,中间操作才会执行。
- 内部迭代: Stream API 在内部处理迭代,你无需编写显式的
for
循环。 - 支持并行处理: 可以轻松地将顺序流转换为并行流,从而利用多核 CPU 优势。
- 操作分类:
- 中间操作 (Intermediate Operations): 返回另一个 Stream,可以链式调用。例如
filter()
,map()
,sorted()
,distinct()
。 - 终端操作 (Terminal Operations): 产生一个非 Stream 的结果(如集合、值、副作用),标志着 Stream 操作的结束。例如
forEach()
,collect()
,reduce()
,count()
,min()
,max()
,findFirst()
。
- 中间操作 (Intermediate Operations): 返回另一个 Stream,可以链式调用。例如
1 | List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); |
4. 默认方法 (Default Methods) 或 接口的扩展方法 (Extension Methods)
Java 8 允许在接口中定义带有方法体的方法,用 default
关键字修饰。这解决了接口演进的问题,在不破坏现有实现类的前提下,向接口添加新的方法。避免了“打破所有现有实现”的问题,允许向已发布的接口添加新功能,同时保持向后兼容性。
1 | interface MyInterface { |
5. Optional 类
java.util.Optional<T>
是一个容器对象,可能包含也可能不包含非 null
值。它被设计用来消除代码中的 NullPointerException
,并提升代码的健壮性和可读性。
作用: 鼓励开发者显式地处理值可能不存在的情况,而不是依赖于
null
检查。常用方法:
Optional.of(value)
: 创建一个包含非空值的 Optional。Optional.ofNullable(value)
: 如果值非空则创建 Optional,否则创建空的 Optional。isPresent()
: 判断 Optional 是否包含值。ifPresent(Consumer)
: 如果值存在,则执行给定的 Consumer 操作。get()
: 获取值,如果 Optional 为空则抛出NoSuchElementException
(不推荐直接使用)。orElse(other)
: 如果值存在则返回,否则返回提供的默认值。orElseGet(Supplier)
: 如果值存在则返回,否则调用 Supplier 获取默认值。orElseThrow(Supplier)
: 如果值存在则返回,否则抛出由 Supplier 创建的异常。
1 | String name = null; |
6. 日期与时间 API
Java 8 引入了全新的、现代化的日期和时间 API ( java.time
包),解决了旧 java.util.Date
和 java.util.Calendar
API 中存在的线程安全、设计缺陷、时区处理复杂等问题。
核心类:
LocalDate
: 不带时间的日期,例如 2023-10-26。LocalTime
: 不带日期的时分秒,例如 10:30:45。LocalDateTime
: 结合了日期和时间,不带时区。ZonedDateTime
: 带有时区的日期和时间。Instant
: 时间线上的一个瞬时点(UTC 时间)。Duration
: 表示时间量(秒和纳秒)。Period
: 表示日历时间量(年、月、日)。DateTimeFormatter
: 用于日期和时间的格式化与解析。
1 | LocalDate today = LocalDate.now(); |