Java 8 新特性

Java 8(2014 年发布)是 Java 历史上最重要的一次升级,让代码从冗长的命令式走向简洁的函数式。核心是 Lambda 表达式Stream 流——处理集合数据时能像写 SQL 一样声明式表达。本节逐个上手最常用的新特性,是学习现代 Java 开发的必由之路。

Lambda 表达式与函数式接口

Lambda 是匿名内部类的简化写法,只能用于函数式接口(只有一个抽象方法,常用 @FunctionalInterface 标注):

// 片段需放进 main 方法中运行
Runnable r1 = new Runnable() {        // 传统写法:匿名内部类
    public void run() { System.out.println("老写法"); }
};
Runnable r2 = () -> System.out.println("Lambda 写法");  // 参数 -> 方法体
r1.run();   // 输出:老写法
r2.run();   // 输出:Lambda 写法

Lambda + Stream 对比示例

以"筛出长度大于 3 的名字并转大写"为例,先看传统循环写法:

// 片段需放进 main 方法中运行
List<String> names = Arrays.asList("lily", "tom", "jerry", "amy");

// 命令式:for + if 手工收集
List<String> old = new ArrayList<>();
for (String n : names) {
    if (n.length() > 3) {
        old.add(n.toUpperCase());
    }
}
System.out.println(old);   // 输出:[LILY, JERRY]

// 声明式:filter → map → collect 流水线
List<String> news = names.stream()
        .filter(n -> n.length() > 3)     // 中间操作:过滤
        .map(String::toUpperCase)        // 中间操作:映射(方法引用)
        .collect(Collectors.toList());   // 终止操作:收集
System.out.println(news);   // 输出:[LILY, JERRY]

两种写法结果相同,Stream 更短、意图更清晰,把 stream() 换成 parallelStream() 还能自动并行计算。

Stream 创建与常用操作

创建流的三种方式与常用中间/终止操作:

// 片段需放进 main 方法中运行
Stream.of("b", "a", "c");             // 方式一:直接创建
Arrays.asList(1, 2, 3).stream();      // 方式二:集合转流
IntStream.range(1, 5);                // 方式三:数值范围

// 链式组合:中间操作可连写,终止操作触发执行
List<Integer> nums = Arrays.asList(3, 1, 2, 3);
nums.stream().sorted().distinct()            // 排序 + 去重
    .forEach(x -> System.out.print(x));      // 输出:123
System.out.println(nums.stream().count());   // 输出:4

filter 过滤、map 转换、sorted 排序、distinct 去重是中间操作;forEach 遍历、collect 收集、count 计数是终止操作。注意:没有终止操作时,中间操作不会真正执行

Optional 简介

Optional 是可能为 null 的值的"容器",用链式方法代替满天飞的判空与空指针:

// 片段需放进 main 方法中运行
Optional<String> o = Optional.ofNullable(null);
System.out.println(o.isPresent());        // 输出:false
System.out.println(o.orElse("默认值"));   // 为空时取默认值,输出:默认值
o.ifPresent(x -> System.out.println(x));  // 有值才执行,这里无输出

默认方法与新日期 API

接口可用 default 定义带方法体的方法,老实现类无需改动即可获得新能力;时间处理上推荐 LocalDate/LocalDateTime + DateTimeFormatter,替代可变的 Date 与 SimpleDateFormat:

// 片段需放进 main 方法中运行
LocalDateTime now = LocalDateTime.now();
System.out.println(now.format(DateTimeFormatter
        .ofPattern("yyyy-MM-dd HH:mm:ss")));   // 输出:当前时间

小结:Java 8 让集合处理进入流式时代——Lambda 简化匿名类,Stream 的 filter/map/collect 取代手写循环,Optional 消灭空指针,LocalDateTime 取代旧日期 API;前三者务必熟练掌握。

笔记加载中…