从 Java 8 迁移到 Java 17 (二):Java 中值得注意的 API 变化

这是上一篇文章的续篇:

从 Java 8 迁移到 Java 17:新功能综合指南

从第 8 版到第 17 版,Java 经历了巨大的演变,实现了多种增强和新的生活质量改进。本文将深入探讨 Java 后续版本中引入的 API 变化和新增功能,我认为这些变化和新增功能对于从 Java 8 迁移到 Java 17 的用户来说最为有趣和有用。

Java 9

Java 9 引入了模块系统,标志着 Java 生态系统发生了重大变革,但同时也带来了一些有价值的 API 增强功能:

Objects.requireNonNullElse

该方法有助于简化对空值的处理,无需进行冗长的空值检查。

Java 8:

String value = (str != null) ? str : "default";

Java 9 :

String value = Objects.requireNonNullElse(str, "default");

Collection 工厂方法

Java 9 中引入了创建不可变 collections 的便捷工厂方法。

Java 8:

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
List<String> unmodifiableList = Collections.unmodifiableList(list);

Java 9 :

List<String> list = List.of("a", "b", "c");

增强型流(Stream) API

为流 API 添加了 takeWhile()dropWhile() 和带谓词的 iterate() 等方法,以便对流进行更多函数式操作。

Java 9 :

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
List<Integer> result = numbers.stream()
                              .takeWhile(n -> n < 4)
                              .collect(Collectors.toList());

CompletableFuture.delayedExecutor()

引入该功能是为了方便安排有延迟的任务。

Java 9 :

Executor executor = CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS);

Collectors.flatMapping()

方便在收集器内进行平面映射操作,这对复杂的还原非常有用。

Java 9 :

List<List<String>> listOfLists = List.of(List.of("a", "b"), List.of("c", "d"));
List<String> flattenedList = listOfLists.stream()
    .collect(Collectors.flatMapping(List::stream, Collectors.toList()));

增强型 Optional

ifPresentOrElse() 等新方法提高了 Optional  类的可用性和灵活性。

Java 9 :

Optional<String> optional = Optional.of("Hello");

optional.ifPresentOrElse(
    value -> System.out.println("Value: " + value),
    () -> System.out.println("No value present")
);

java.util.concurrent.Flow

为支持反应流而引入。

Java 9 :

import java.util.concurrent.Flow;

Java 10

Java 10 延续了渐进式改进的趋势,更加注重性能和可用性的调整:

局部变量类型推断(var)

var 关键字虽然不是 API 的改动,但它允许更简洁的变量声明并提高了可读性。

Java 10 :

var list = new ArrayList<Map<String, List<Integer>>>();

不可修改的 Collections

引入了 List.copyOf()Set.copyOf()Map.copyOf() 等方法,用于创建不可修改的集合副本。

Java 8:

List<String> list = new ArrayList<>();
list.add("a");
List<String> unmodifiableList = Collections.unmodifiableList(list);

Java 10 :

List<String> list = List.copyOf(originalList);

Optional 增强

添加了不带参数的 orElseThrow() 方法。

Java 10 :

Optional<String> optional = Optional.empty();
String value = optional.orElseThrow(); // Throws NoSuchElementException

Java 11

Java 11 带来了几个值得注意的 API 增强功能,特别是在String操作和InputStream处理方面:

String 增强

String类增加了 repeat(int) 方法,可轻松重复字符串。

Java 8:

String repeated = String.join("", Collections.nCopies(3, "abc"))

Java 11 :

String repeated = "abc".repeat(3);

InputStream 增强

引入了 readNBytes(int),以便更有控制地从 InputStream 读取字节。

Java 8:

byte[] buffer = new byte[10];
int bytesRead = inputStream.read(buffer, 0, 10);

Java 11 :

byte[] buffer = inputStream.readNBytes(10);

新 Files 方法

添加了 writeString()readString() 方法,以简化文件 I/O 操作。

Java 8:

Files.write(Paths.get("file.txt"), "Hello, World!".getBytes(StandardCharsets.UTF_8));
String content = new String(Files.readAllBytes(Paths.get("file.txt")), StandardCharsets.UTF_8);

Java 11 :

Files.writeString(Path.of("file.txt"), "Hello, World!", StandardCharsets.UTF_8);
String content = Files.readString(Path.of("file.txt"), StandardCharsets.UTF_8);

Java 12

单文件源代码程序

可直接运行单个 Java 源文件,简化了小型快速脚本和测试的流程。

Java 8:

javac HelloWorld.java
java HelloWorld

Java 12 :

java HelloWorld.java

Switch 表达式(预览)

为 switch 语句引入了多大小写标签,现在这些语句也可以直接返回值,从而无需单独的赋值语句。

Java 12 Example (Preview):

int numLetters = switch (day) {
    case "MONDAY", "FRIDAY", "SUNDAY":
        yield 6;
    case "TUESDAY":
        yield 7;
    case "THURSDAY", "SATURDAY":
        yield 8;
    case "WEDNESDAY":
        yield 9;
    default:
        throw new IllegalArgumentException("Unexpected day: " + day);
};

Java 14

Switch 表达式 (标准功能)

switch 语句的新箭头语法使流程更加简洁,不再需要穿透语义。该功能在 Java 14 中成为标准功能。

Java 8:

int numLetters;
switch (day) {
    case "MONDAY":
    case "FRIDAY":
    case "SUNDAY":
        numLetters = 6;
        break;
    case "TUESDAY":
        numLetters = 7;
        break;
    case "THURSDAY":
    case "SATURDAY":
        numLetters = 8;
        break;
    case "WEDNESDAY":
        numLetters = 9;
        break;
    default:
        throw new IllegalArgumentException("Unexpected day: " + day);
}

Java 14 :

int numLetters = switch (day) {
    case "MONDAY", "FRIDAY", "SUNDAY" -> 6;
    case "TUESDAY" -> 7;
    case "THURSDAY", "SATURDAY" -> 8;
    case "WEDNESDAY" -> 9;
    default -> throw new IllegalArgumentException("Unexpected day: " + day);
};

Java 15

文本块

正式从预览版毕业,为处理多行字符串提供了一种简洁的方法。

Java 15 :

String sqlQuery = """
                  SELECT id, name, age
                  FROM users
                  WHERE age > 30
                  ORDER BY age DESC
                  """;

字符串格式化方法

引入 String::formatted 方法是为了获得更好的字符串格式化能力。

Java 8:

String formatted = String.format("Name: %s, Age: %d", name, age);

Java 15 :

String formatted = "Name: %s, Age: %d".formatted(name, age);

Java 16

Records

引入 record 类,以减少创建简单数据载体类时的模板。

Java 8:

public class Person {
    private final String name;
    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }

    @Override
    public boolean equals(Object o) { 
        // equality logic 
    }

    @Override
    public int hashCode() { 
        // hashcode logic 
    }

    @Override
    public String toString() { 
        // toString logic 
    }
}

Java 16 :

public record Person(String name, int age) {}

针对 instanceof 的模式匹配

通过为 instanceof 引入模式匹配,简化了构建。

Java 8:

if (obj instanceof String) {
    String str = (String) obj;
    // Use str
}

Java 16 :

if (obj instanceof String str) {
    // Use str directly
}

Stream.toList()

添加了一种方便的方法,可将流元素直接收集到不可修改的列表中。

Java 8:

List<String> list = stream.collect(Collectors.toList());//mutable

Java 16 :

List<String> list = stream.toList(); //unmodifiable

Java 17

十六进制二进制数据表示

Java 17 提供了以十六进制形式表示二进制数据的实用程序,这对调试非常有用

Java 17 :

byte[] data = new byte[] { 0x1A, 0x2B, 0x3C };
String hex = HexFormat.of().formatHex(data);
System.out.println(hex); // Outputs: 1a2b3c

ZoneId.ofOffset()

已添加 ZoneId.ofOffset(),可直接从偏移量创建区域 ID。

Java 8:

ZoneId zone = ZoneId.of("UTC+01:00");

Java 17 :

ZoneId zone = ZoneId.ofOffset("UTC", ZoneOffset.ofHours(1));

你也许感兴趣的:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注