Java 8新特性
Java 8新特性[编辑 | 编辑源代码]
Java 8 是 Java 编程语言的一个重要版本,于2014年发布。它引入了许多革命性的新特性,旨在提高开发效率、代码可读性和性能。这些特性包括 Lambda 表达式、Stream API、新的日期时间 API、默认方法等。本章将详细介绍这些特性及其应用。
Lambda 表达式[编辑 | 编辑源代码]
Lambda 表达式是 Java 8 最显著的特性之一,它允许以简洁的方式实现函数式接口(Functional Interface)。Lambda 表达式使得代码更加简洁,并支持函数式编程风格。
语法[编辑 | 编辑源代码]
Lambda 表达式的语法如下:
(parameters) -> expression
或
(parameters) -> { statements; }
示例[编辑 | 编辑源代码]
以下是一个简单的 Lambda 表达式示例,用于实现 `Runnable` 接口:
// Java 7 之前的写法
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello World!");
}
};
// Java 8 使用 Lambda 表达式
Runnable r2 = () -> System.out.println("Hello World!");
输出[编辑 | 编辑源代码]
Hello World!
解释[编辑 | 编辑源代码]
Lambda 表达式 `() -> System.out.println("Hello World!")` 替代了匿名内部类的冗长写法,使代码更加简洁。
Stream API[编辑 | 编辑源代码]
Stream API 是 Java 8 引入的一个新的抽象层,用于处理集合数据。它支持函数式编程风格,可以高效地进行过滤、映射、归约等操作。
示例[编辑 | 编辑源代码]
以下是一个使用 Stream API 过滤和打印列表元素的示例:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 使用 Stream 过滤并打印名字长度大于 3 的元素
names.stream()
.filter(name -> name.length() > 3)
.forEach(System.out::println);
输出[编辑 | 编辑源代码]
Alice Charlie David
解释[编辑 | 编辑源代码]
- `stream()` 方法将集合转换为流。 - `filter()` 方法过滤出满足条件的元素(这里条件是名字长度大于 3)。 - `forEach()` 方法遍历流中的元素并打印。
新的日期时间 API[编辑 | 编辑源代码]
Java 8 引入了 `java.time` 包,提供了全新的日期时间 API,解决了旧版 `java.util.Date` 和 `java.util.Calendar` 的诸多问题。
示例[编辑 | 编辑源代码]
以下是一个使用新日期时间 API 的示例:
// 获取当前日期
LocalDate today = LocalDate.now();
System.out.println("Today: " + today);
// 计算明天的日期
LocalDate tomorrow = today.plusDays(1);
System.out.println("Tomorrow: " + tomorrow);
// 格式化日期
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
String formattedDate = tomorrow.format(formatter);
System.out.println("Formatted Date: " + formattedDate);
输出[编辑 | 编辑源代码]
Today: 2023-10-01 Tomorrow: 2023-10-02 Formatted Date: 02-10-2023
解释[编辑 | 编辑源代码]
- `LocalDate` 表示不带时间的日期。 - `plusDays()` 方法用于计算未来日期。 - `DateTimeFormatter` 用于格式化日期。
默认方法[编辑 | 编辑源代码]
默认方法(Default Methods)允许接口包含具体实现的方法,而不仅仅是抽象方法。这是为了支持向后兼容性,特别是在为集合框架添加新功能时。
示例[编辑 | 编辑源代码]
以下是一个包含默认方法的接口示例:
interface Greeting {
void sayHello(String name);
default void sayBye(String name) {
System.out.println("Goodbye, " + name);
}
}
public class Main implements Greeting {
@Override
public void sayHello(String name) {
System.out.println("Hello, " + name);
}
public static void main(String[] args) {
Main main = new Main();
main.sayHello("Alice");
main.sayBye("Alice");
}
}
输出[编辑 | 编辑源代码]
Hello, Alice Goodbye, Alice
解释[编辑 | 编辑源代码]
- `Greeting` 接口定义了一个抽象方法 `sayHello` 和一个默认方法 `sayBye`。 - `Main` 类实现了 `Greeting` 接口,并可以选择是否重写默认方法。
方法引用[编辑 | 编辑源代码]
方法引用(Method References)是 Lambda 表达式的一种简化写法,用于直接引用已有方法。
示例[编辑 | 编辑源代码]
以下是一个使用方法引用的示例:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用方法引用打印每个元素
names.forEach(System.out::println);
输出[编辑 | 编辑源代码]
Alice Bob Charlie
解释[编辑 | 编辑源代码]
`System.out::println` 是 `System.out.println()` 方法的方法引用,等效于 Lambda 表达式 `x -> System.out.println(x)`。
Optional 类[编辑 | 编辑源代码]
`Optional` 是 Java 8 引入的一个容器类,用于解决 `NullPointerException` 问题。它可以明确表示一个值可能为 `null`。
示例[编辑 | 编辑源代码]
以下是一个使用 `Optional` 的示例:
Optional<String> name = Optional.ofNullable(getName());
System.out.println(name.orElse("Default Name"));
String getName() {
return null; // 模拟可能返回 null 的方法
}
输出[编辑 | 编辑源代码]
Default Name
解释[编辑 | 编辑源代码]
- `Optional.ofNullable()` 创建一个 `Optional` 对象,允许值为 `null`。 - `orElse()` 方法在值为 `null` 时返回默认值。
实际应用案例[编辑 | 编辑源代码]
以下是一个结合 Lambda 表达式和 Stream API 的实际案例,用于统计员工列表中薪资高于平均值的员工:
class Employee {
String name;
double salary;
Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public double getSalary() { return salary; }
public String getName() { return name; }
}
public class Main {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("Alice", 5000),
new Employee("Bob", 6000),
new Employee("Charlie", 7000)
);
double averageSalary = employees.stream()
.mapToDouble(Employee::getSalary)
.average()
.orElse(0);
System.out.println("Average Salary: " + averageSalary);
employees.stream()
.filter(e -> e.getSalary() > averageSalary)
.forEach(e -> System.out.println(e.getName()));
}
}
输出[编辑 | 编辑源代码]
Average Salary: 6000.0 Charlie
解释[编辑 | 编辑源代码]
- `mapToDouble()` 将员工对象映射为薪资值。 - `average()` 计算平均薪资。 - `filter()` 过滤出薪资高于平均值的员工。
总结[编辑 | 编辑源代码]
Java 8 的新特性极大地提升了开发效率和代码可读性。Lambda 表达式、Stream API、新的日期时间 API、默认方法等特性使得 Java 更适合现代编程需求。通过本章的学习,读者应能掌握这些特性的基本用法,并在实际项目中灵活运用。