JDK JDK 学习手册8 → 27 · JDK 专用学习站
CHEATSHEET · JDK 8

JDK 8 一页速查卡

JDK 8 · 4 个分区 · 12 张卡片 · A4 打印优化
返回速查模块
怎么用4 个分区、12 张卡片,把 JDK 8 最常用的写法与版本边界压缩到一张可打印的页面。适合贴在显示器旁,或面试前十分钟扫一遍。
4 个分区12 张卡片A4 打印优化基于 JDK 8
FUNCTIONAL

函数式与流

3
Lambda

四种写法与目标类型

Function<String, Integer> len = String::length;
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
Supplier<List<String>> list = ArrayList::new;
Runnable r = () -> System.out.println("run");

Lambda 只能绑定函数式接口;参数类型可省略,返回类型由上下文推断。

Stream

三段式流水线

List<String> out = names.stream()
        .filter(n -> n.length() > 3)
        .map(String::toUpperCase)
        .sorted()
        .collect(Collectors.toList());

中间操作惰性;终止操作才执行;流只能消费一次。

并行

parallel 的边界

  • 适合:大数据量、CPU 密集、无状态、可结合的操作
  • 不适合:I/O、小数据、共享可变状态、强顺序依赖
  • 默认使用 ForkJoinPool.commonPool(),并行度约为 CPU-1

并行流不会自动更快;forEach 不保证顺序,需要顺序时用 forEachOrdered。

OPTIONAL / TIME

Optional 与时间

3
Optional

只放在返回值上

Optional<User> user = repo.find(id);
String name = user.map(User::name).orElse("anonymous");

不要用于字段、参数、集合元素;Optional.of(null) 直接 NPE。

求值

orElse vs orElseGet

opt.orElse(expensive());          // 总会求值
opt.orElseGet(() -> expensive()); // 为空才求值
opt.orElseThrow(() -> new IllegalStateException());

默认值昂贵或有副作用时,必须用 orElseGet。

java.time

类型地图

  • Instant:时间线上的点,UTC 纪元
  • LocalDate / LocalDateTime:无时区的人类时间
  • ZonedDateTime:带 ZoneId 与 DST 规则
  • Duration 表示时长,Period 表示日期跨度

全部不可变;格式化用 DateTimeFormatter,可复用。

INTERFACE / COLLECTIONS

接口与集合

3
default

默认方法与冲突

interface A { default String tag() { return "A"; } }
interface B { default String tag() { return "B"; } }

class C implements A, B {
    public String tag() { return A.super.tag() + B.super.tag(); }
}

类优先于接口;子接口优先于父接口;否则必须显式覆盖。

static

接口静态方法

interface Named {
    static Named of(String name) { return () -> name; }
}
Named n = Named.of("Ada"); // 只能通过接口名调用

static 方法不被实现类继承;接口不能有实例字段。

HashMap

阈值速记

  • 默认容量 16,负载因子 0.75,阈值 12
  • 扩容翻倍;容量必须是 2 的幂
  • 链表超过 8 且容量 ≥ 64 才树化
  • 扩容拆分时树节点 ≤ 6 退回链表

第 9 个节点插入才触发树化;容量不足 64 时先扩容。

MIGRATION

迁移与运行时

3
Metaspace

PermGen 已移除

-XX:MetaspaceSize=64m
-XX:MaxMetaspaceSize=256m

Metaspace 在本地内存;默认不设上限。-XX:MaxPermSize 在 8 只警告,9+ 启动失败。

编译

class 版本与 source

javac -source 1.8 -target 1.8 App.java
javap -verbose App.class | grep major   # 52

JDK 8 没有 --release;-source 1.7 下 lambda 直接编译失败。

边界

8 里没有这些

  • var(10)、List.of / Map.of(9)
  • Files.readString、String.isBlank、HttpClient(11)
  • record(16)、sealed(17)、文本块(15)
  • Stream.toList(16)、Optional.isEmpty(11)

写 JDK 8 代码时,IDE 的 SDK 与语言级别都要锁到 8。

4 个最容易记错的点TRAPS

树化不是第 8 个节点

JDK 8 在桶内已有 8 个节点、插入第 9 个时才调用 treeifyBin;容量小于 64 时先扩容,不会树化。

orElse 总会求值

orElse(expensive()) 在 Optional 有值时也会执行参数表达式;需要惰性求值用 orElseGet。

并行流共享状态

在 parallel stream 里对 ArrayList add、对计数器 ++ 都会丢更新;用 collect/reduce 或线程安全结构,并注意 commonPool 被阻塞。

MaxPermSize 在 8 只是警告

JDK 8 会打印 ignoring option 并继续启动;JDK 9+ 变成 Unrecognized VM option,直接失败。升级时应删除,而不是保留。

继续深入NEXT

返回速查模块

内容基于本机 JDK 1.8.0_281 编译/运行验证;版本边界按 JDK 8 正式 API 标注,未使用 9+ 能力。

JDK 学习手册 · JDK / Java 专用学习站 · 纯静态 · 双击 index.html 即可使用

本站专注 JDK 版本演进与 Java 教学,非 Oracle / OpenJDK 官方站点。版本数据来自 OpenJDK 官方 Features 表;课程示例已在对应本机 JDK 实测。构建日期 2026-11-12。