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
方法、equals
、hashCode
和 toString
方法。
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 正式成为标准特性。
-
字符串模板(预览特性)
- 特性说明 :提供了一种更简洁、直观的方式来构建字符串,使用
STR
或FMT
作为字符串模板的引导词。 - 示例代码:
- 特性说明 :提供了一种更简洁、直观的方式来构建字符串,使用
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)
- 特性说明 :为
List
、Deque
等集合接口添加了新的方法,以支持顺序相关的操作,如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());
}
}