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()); 
    }
}
相关推荐
武帝为此3 分钟前
【Maven教程与实战案例】
java·maven
杨凯凡3 分钟前
深入理解Tomcat:Java Web服务器的安装与配置
java·tomcat
uhakadotcom8 分钟前
使用Docker容器化部署Python应用:一步步教你从本地到VPS服务器
后端·面试·github
unique_pursuit9 分钟前
Go Context深度剖析
开发语言·后端·golang
lanssssss12 分钟前
数据结构及算法(JAVA)
java·数据结构·算法
歪歪歪。。14 分钟前
黑马程序员javaweb案例---初识管理系统(spring-boot)
java·spring boot·sql·tomcat·maven
August_._20 分钟前
【JavaWeb】快速入门——HTML&CSS
java·css·vscode·前端框架·html·web
裁二尺秋风22 分钟前
CI/CD—Jenkins、Maven安装
java·ci/cd·maven
Asthenia041240 分钟前
chmod 和 chown 区别咋分?记忆小妙招来了!
后端
泉城老铁44 分钟前
使用springboot+Elasticsearch搭建本地化知识库搜索
后端