深入理解 Java 8:从语法到思想的革命
一、Java 8 带来了什么?
Java 8 是 Java 语言发展史上的一个里程碑,它不仅仅是语法糖的堆砌,而是一次编程思想的现代化重塑。
在 Java 8 之前,Java 一直被批评为“过于面向对象而不够函数化”,而自 Java 8 起,函数式编程、流式操作、并行计算等特性成为核心。
二、主要特性一览
| 特性 | 作用 | 示例 |
|---|---|---|
| Lambda 表达式 | 简化匿名内部类的写法 | (a, b) -> a + b |
| Stream API | 让集合操作更简洁、更高效 | list.stream().filter(...).collect(...) |
| Optional 类 | 优雅地避免 NullPointerException | Optional.ofNullable(obj) |
| 新的日期时间 API | 替代 Date / Calendar | LocalDate.now() |
| 接口默认方法 | 为接口添加默认实现 | default void run(){} |
| Nashorn JavaScript 引擎 | 在 JVM 上执行 JS | ScriptEngineManager |
| 并行流 (Parallel Stream) | 自动利用多核 CPU 并行处理 | list.parallelStream() |
三、Lambda 表达式:让函数成为一等公民
1. 背景
在 Java 8 之前,匿名内部类代码冗长:
new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Hello Java 7");}
}).start();
2. Java 8 的改进
new Thread(() -> System.out.println("Hello Java 8")).start();
简洁、高效且可读性更强。
3. Lambda 的语法规则
| 语法 | 示例 | 说明 |
|---|---|---|
| 无参数 | () -> System.out.println("Hi") | 无参数时用空括号 |
| 单参数 | x -> x * x | 参数可省略类型 |
| 多参数 | (a, b) -> a + b | 多个参数用括号 |
| 带类型 | (int a, int b) -> a + b | 显式声明类型 |
| 多语句 | (a, b) -> { int c = a + b; return c; } | 使用花括号和 return |
四、函数式接口(Functional Interface)
Lambda 依赖于 函数式接口:只有一个抽象方法的接口。
@FunctionalInterface
interface Calculator {int compute(int a, int b);
}public class Demo {public static void main(String[] args) {Calculator add = (a, b) -> a + b;System.out.println(add.compute(3, 4)); // 输出 7}
}
Java 8 内置了大量函数式接口,例如:
Predicate<T>、Function<T,R>、Consumer<T>、Supplier<T>。
五、Stream API:集合操作的革命
1. 传统集合 VS Stream
| 操作 | Java 7 | Java 8 |
|---|---|---|
| 过滤 | 手动循环、判断 | .filter() |
| 排序 | Collections.sort() | .sorted() |
| 映射 | 手动转换 | .map() |
| 统计 | 手动计数 | .count() |
| 并行 | 手动开启线程 | .parallelStream() |
2. 实例:筛选、排序、映射
import java.util.*;
import java.util.stream.*;public class StreamDemo {public static void main(String[] args) {List<String> names = Arrays.asList("Tom", "Jerry", "Mickey", "Donald");names.stream().filter(name -> name.startsWith("D")).map(String::toUpperCase).sorted().forEach(System.out::println);}
}
输出:
DONALD
3. Stream 的工作原理
数据源 → 中间操作(filter, map) → 终端操作(forEach, collect)
4. 并行流 ParallelStream
list.parallelStream().filter(...).map(...).forEach(System.out::println);
⚡ 自动并行化处理,轻松利用多核 CPU。
六、Optional:告别 NullPointerException
Optional<String> name = Optional.ofNullable(null);
System.out.println(name.orElse("默认值"));
输出:
默认值
Optional 常用方法
| 方法 | 功能 |
|---|---|
ofNullable() | 创建可空 Optional |
isPresent() | 判断是否非空 |
orElse() | 值为空时返回默认值 |
ifPresent() | 值非空时执行 lambda |
map() | 映射转换 |
七、新的日期时间 API:告别 Calendar
import java.time.*;public class DateDemo {public static void main(String[] args) {LocalDate today = LocalDate.now();LocalDate birth = LocalDate.of(1995, 11, 4);Period period = Period.between(birth, today);System.out.println("年龄:" + period.getYears());}
}
与旧 API 的对比
| 旧版 | 新版 |
|---|---|
java.util.Date | java.time.LocalDate |
java.util.Calendar | java.time.LocalDateTime |
SimpleDateFormat | DateTimeFormatter |
新 API 基于 Joda-Time,线程安全、不可变、API 语义清晰。
八、接口默认方法(Default Method)
在 Java 8 之前,接口一旦发布,新增方法会破坏兼容性。
Java 8 允许为接口定义默认实现。
interface Animal {default void sound() {System.out.println("Some sound...");}
}class Dog implements Animal {public void sound() {System.out.println("Woof!");}
}public class Demo {public static void main(String[] args) {new Dog().sound();}
}
这使得接口演进更灵活,不会破坏已有实现类。
九、Java 8 的并行能力
Stream API 提供了简洁的并行计算支持。
只需一行 .parallelStream(),即可让任务自动分配到多核 CPU:
list.parallelStream().map(String::toUpperCase).forEach(System.out::println);
内部基于 ForkJoinPool,实现了自动分治计算。
十、Java 8 对性能的影响
| 项目 | Java 7 | Java 8 |
|---|---|---|
| 匿名内部类 | 创建新类对象 | 内联优化 |
| 集合处理 | 单线程 | 可并行化 |
| Null 处理 | 容易 NPE | Optional 机制 |
| 时间 API | 可变且线程不安全 | 不可变、线程安全 |
十一、Lambda、Stream、Optional 协作示例
List<String> names = Arrays.asList("Tom", "Jerry", null, "Donald");names.stream().filter(Objects::nonNull).map(String::toUpperCase).map(Optional::ofNullable).forEach(opt -> System.out.println(opt.orElse("未知")));
输出:
TOM
JERRY
DONALD
十二、总结
| 特性 | 优点 | 场景 |
|---|---|---|
| Lambda | 简化回调与函数式表达 | 事件监听、线程任务 |
| Stream | 支持链式流式处理 | 集合计算、并行处理 |
| Optional | 避免空指针 | 参数返回值处理 |
| Date/Time API | 新的时间操作方式 | 时间计算、格式化 |
| 默认方法 | 接口演化 | 框架兼容设计 |
延伸阅读:
- Java 官方文档:Lambda Expressions
- Stream API 详解
