Java 新特性全解析:从 Lambda 到虚拟线程,一文掌握最新演进

Lambda 表达式

1. 概念

Lambda 表达式是 Java 8 引入的一种简洁的语法,用于创建匿名函数。它允许将函数作为参数传递给方法,或者将代码作为数据处理,从而使代码更简洁、更具可读性。

2. 基本语法

  • 无参数,无返回值() -> System.out.println("Hello");
  • 一个参数,无返回值(x) -> System.out.println(x); ,也可省略括号 x -> System.out.println(x);
  • 多个参数,有返回值(x, y) -> x + y; ,若语句块不止一条语句,需使用花括号并显式使用 return 语句,如 (x, y) -> { int result = x + y; return result; }

3. 函数式接口

  • Lambda 表达式需要一个函数式接口作为目标类型。函数式接口是只包含一个抽象方法的接口,可使用 @FunctionalInterface 注解确保其符合规范。
  • 例如,java.util.function 包下提供了很多常用的函数式接口,如 Predicate<T>(接收一个参数,返回布尔值)、Function<T, R>(接收一个参数,返回另一个类型的值)、Consumer<T>(接收一个参数,无返回值)等。
java 复制代码
import java.util.function.Predicate;

public class LambdaWithFunctionalInterface {
    public static void main(String[] args) {
        Predicate<Integer> isEven = num -> num % 2 == 0;
        System.out.println(isEven.test(4)); 
    }
}

4. 方法引用

  • 方法引用是 Lambda 表达式的一种更简洁形式,它允许直接引用已有的方法。

  • 常见的方法引用类型有:

    • 静态方法引用ClassName::staticMethod
    • 实例方法引用instance::instanceMethod
    • 构造方法引用ClassName::new
java 复制代码
import java.util.Arrays;
import java.util.List;

public class MethodReferenceExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        names.forEach(System.out::println); 
    }
}

Stream API

1. 概念

Stream API 是 Java 8 引入的用于处理集合数据的强大工具,它提供了一种声明式的方式来处理数据,支持链式操作,提高了代码的可读性和可维护性。

2. 流的创建

  • 从集合创建Collection.stream()Collection.parallelStream()(并行流)
  • 从数组创建Arrays.stream(array)
  • 使用 Stream.of()Stream.of("a", "b", "c")
java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamCreation {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        Stream<Integer> streamFromList = numbers.stream();

        int[] intArray = {1, 2, 3};
        java.util.stream.IntStream streamFromArray = Arrays.stream(intArray);

        Stream<String> streamFromOf = Stream.of("apple", "banana", "cherry");
    }
}

3. 中间操作

  • 中间操作会返回一个新的流,可进行链式调用。常见的中间操作有:

    • filter :过滤元素,接收一个 Predicate 函数式接口。
    • map :将元素进行转换,接收一个 Function 函数式接口。
    • sorted:对元素进行排序。
    • distinct:去除重复元素。
java 复制代码
import java.util.Arrays;
import java.util.List;

public class StreamIntermediateOperations {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        numbers.stream()
               .filter(n -> n % 2 == 0)
               .map(n -> n * 2)
               .forEach(System.out::println);
    }
}

4. 终端操作

  • 终端操作会触发流的处理并产生一个结果或副作用。常见的终端操作有:

    • forEach:对每个元素执行操作。
    • collect:将流中的元素收集到一个集合中。
    • reduce:将流中的元素进行归约操作。
    • count:统计元素数量。
java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamTerminalOperations {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> evenNumbers = numbers.stream()
                                           .filter(n -> n % 2 == 0)
                                           .collect(Collectors.toList());
        System.out.println(evenNumbers);
    }
}

模块化(Java 9+)

1. 概念

Java 9 引入了模块化系统(Jigsaw 项目),旨在解决大型项目中依赖管理和代码隔离的问题。模块化将代码组织成模块,每个模块有明确的边界和依赖关系。

2. 模块声明文件

  • 每个模块需要一个 module-info.java 文件,位于模块的根目录下。该文件用于声明模块的名称、依赖的模块以及导出的包。
java 复制代码
// module-info.java
module myModule {
    requires otherModule; // 声明依赖的模块
    exports com.example.mypackage; // 声明导出的包
}

3. 模块的依赖关系

  • 模块之间通过 requires 关键字声明依赖关系,确保模块只能访问其明确声明依赖的模块中的公共类和包。
  • 还可以使用 requires transitive 来传递依赖,使得依赖该模块的其他模块也能自动依赖被传递的模块。

4. 模块的封装性

  • 模块可以通过 exports 关键字控制哪些包对外可见,未导出的包对于其他模块是不可见的,从而增强了代码的封装性和安全性。

记录类(Java 14+)

1. 概念

记录类(Record)是 Java 14 引入的一种特殊类,用于简化不可变数据类的创建。它可以自动生成构造方法、getter 方法、equalshashCodetoString 方法。

2. 基本语法

java 复制代码
record Person(String name, int age) { }

public class RecordExample {
    public static void main(String[] args) {
        Person person = new Person("Alice", 25);
        System.out.println(person.name()); 
        System.out.println(person.age()); 
        System.out.println(person); 
    }
}

3. 特性

  • 不可变性 :记录类的属性是 final 的,一旦创建就不能修改。
  • 紧凑构造方法:可以定义紧凑构造方法来对属性进行验证或初始化操作。
java 复制代码
record Point(int x, int y) {
    public Point {
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("Coordinates cannot be negative");
        }
    }
}

4. 与普通类的比较

  • 记录类的代码更简洁,减少了样板代码的编写,适合用于表示简单的数据载体。而普通类在需要更多灵活性和复杂行为时使用。

Java 15

  • 密封类(Sealed Classes)

    • 特性说明 :密封类和接口限制了哪些其他类或接口可以扩展或实现它们。使用 sealed 关键字修饰类或接口,通过 permits 子句明确列出允许的子类或实现类。
    • 示例代码
java 复制代码
public sealed class Shape permits Circle, Rectangle {
    // 类体
}

final class Circle extends Shape {
    // 类体
}

final class Rectangle extends Shape {
    // 类体
}

Java 16

  • 模式匹配(Pattern Matching for instanceof)

    • 特性说明 :增强了 instanceof 运算符,允许在进行类型检查的同时进行类型转换并赋值给一个变量,减少了代码的冗余。
    • 示例代码
java 复制代码
Object obj = "Hello";
if (obj instanceof String str) {
    System.out.println(str.length());
}
  • Records 正式转正:在 Java 14 中作为预览特性引入的记录类(Records),在 Java 16 中正式成为标准特性。

Java 17

  • 密封类正式转正:密封类在 Java 15 作为预览特性引入,Java 17 正式成为标准特性。
  • 新的 macOS 渲染管道:在 macOS 平台上,Java 17 引入了基于 Apple Metal API 的新渲染管道,改善了图形性能和视觉质量。

Java 18

  • UTF-8 标准默认编码:将 UTF - 8 设置为标准默认字符编码,简化了字符编码的处理,减少了编码相关的错误。
  • Simple Web Server :引入了一个简单的命令行 Web 服务器,方便开发者进行快速的静态文件服务和测试。通过命令 jwebserver 即可启动。

Java 19

  • 虚拟线程(Virtual Threads,预览特性)

    • 特性说明:虚拟线程是轻量级的线程,由 JVM 调度,能够显著提高 Java 应用程序在处理大量并发任务时的性能和资源利用率。
    • 示例代码
java 复制代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class VirtualThreadExample {
    public static void main(String[] args) {
        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int i = 0; i < 1000; i++) {
                executor.submit(() -> {
                    System.out.println(Thread.currentThread().getName());
                });
            }
        }
    }
}

Java 20

  • 模式匹配增强(Pattern Matching for switch,预览特性)

    • 特性说明 :允许在 switch 表达式和语句中使用模式匹配,使得代码更加简洁和强大。
    • 示例代码
java 复制代码
Object obj = 5;
switch (obj) {
    case Integer i -> System.out.println("It's an integer: " + i);
    case String s -> System.out.println("It's a string: " + s);
    default -> System.out.println("Unknown type");
}

Java 21

  • 虚拟线程正式转正:虚拟线程在 Java 19 作为预览特性引入,Java 21 正式成为标准特性。

  • 字符串模板(预览特性)

    • 特性说明 :提供了一种更简洁、直观的方式来构建字符串,使用 STRFMT 作为字符串模板的引导词。
    • 示例代码
java 复制代码
String name = "Alice";
int age = 25;
String message = STR."My name is {name} and I'm {age} years old.";
System.out.println(message);
  • 序列集合(Sequenced Collections)

    • 特性说明 :为 ListDeque 等集合接口添加了新的方法,以支持顺序相关的操作,如 first()last() 等。
    • 示例代码
java 复制代码
import java.util.ArrayList;
import java.util.SequencedCollection;

public class SequencedCollectionExample {
    public static void main(String[] args) {
        SequencedCollection<String> sequencedList = new ArrayList<>();
        sequencedList.add("A");
        sequencedList.add("B");
        System.out.println(sequencedList.first()); 
        System.out.println(sequencedList.last()); 
    }
}
相关推荐
曹牧5 分钟前
文档格式:OFD
java
豆角焖肉30 分钟前
Maven进阶与搭建私服
java·maven
大不点wow41 分钟前
Java序列化与反序列化:让对象走出JVM
java·开发语言·jvm
止语Lab1 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活1 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
噢,我明白了1 小时前
Java中日期和字符串的处理
java·开发语言·日期
程序员天天困1 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn1 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
dkbnull1 小时前
Spring Boot请求处理组件对比详解
java·spring boot
jun_bai1 小时前
Orthanc服务器使用java上传dicom影像文件
java·运维·服务器