Java8核心特性详解
1. Java8概述
Java 8是Java语言发展史上的一个重要里程碑,于2014年3月发布。它引入了许多革命性的新特性,极大地提升了开发效率和代码可读性。本文将详细介绍Java 8的四大核心特性:
- Lambda表达式 - 函数式编程支持
- Stream API - 集合处理新方式
- 新日期时间API - 解决旧Date/Calendar的问题
- 接口默认方法 - 接口的演进能力
2. Lambda表达式
2.1 什么是Lambda表达式
Lambda表达式是Java 8中最重要的新特性之一,它允许把函数作为一个方法的参数(函数作为参数传递进方法中),使代码更加简洁紧凑。
2.2 Lambda语法
基本语法:
1 2 3
| (parameters) -> expression 或 (parameters) -> { statements; }
|
2.3 Lambda示例
示例1:无参数
1
| () -> System.out.println("Hello Lambda");
|
示例2:一个参数
1
| str -> System.out.println(str);
|
示例3:多个参数
示例4:带返回值
1 2 3 4
| (String s1, String s2) -> { System.out.println("Comparing " + s1 + " and " + s2); return s1.compareTo(s2); }
|
2.4 函数式接口
Lambda表达式需要函数式接口的支持。函数式接口是指仅包含一个抽象方法的接口。Java 8提供了@FunctionalInterface
注解来标识函数式接口。
1 2 3 4 5 6 7 8 9 10 11
| @FunctionalInterface interface MyFunctionalInterface { void execute(); }
public class Main { public static void main(String[] args) { MyFunctionalInterface fi = () -> System.out.println("Executing..."); fi.execute(); } }
|
2.5 Java内置函数式接口
Java 8在java.util.function
包中提供了许多内置函数式接口:
- Consumer - 接受一个输入参数,无返回值
- Supplier - 无参数,返回一个结果
- Function<T,R> - 接受一个输入参数,返回一个结果
- Predicate - 接受一个输入参数,返回布尔值
- BiFunction<T,U,R> - 接受两个输入参数,返回一个结果
3. Stream API
3.1 什么是Stream
Stream是Java 8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤和映射数据等操作。
3.2 Stream特点
- 不是数据结构:不存储数据
- 不修改源数据:对Stream的操作会产生新Stream
- 惰性执行:中间操作是惰性的
- 可消费性:Stream只能被消费一次
3.3 创建Stream
从集合创建
1 2
| List<String> list = Arrays.asList("a", "b", "c"); Stream<String> stream = list.stream();
|
从数组创建
1 2
| String[] array = {"a", "b", "c"}; Stream<String> stream = Arrays.stream(array);
|
使用Stream.of()
1
| Stream<String> stream = Stream.of("a", "b", "c");
|
生成无限流
1
| Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);
|
3.4 中间操作
filter() - 过滤
1
| list.stream().filter(s -> s.startsWith("a"));
|
map() - 映射
1
| list.stream().map(String::toUpperCase);
|
sorted() - 排序
distinct() - 去重
1
| list.stream().distinct();
|
limit() - 限制数量
1
| list.stream().limit(10);
|
3.5 终止操作
forEach() - 遍历
1
| list.stream().forEach(System.out::println);
|
collect() - 收集
1
| List<String> newList = list.stream().collect(Collectors.toList());
|
count() - 计数
1
| long count = list.stream().count();
|
reduce() - 归约
1
| Optional<String> reduced = list.stream().reduce((s1, s2) -> s1 + "#" + s2);
|
anyMatch()/allMatch()/noneMatch() - 匹配
1
| boolean anyStartsWithA = list.stream().anyMatch(s -> s.startsWith("a"));
|
3.6 并行流
1
| list.parallelStream().forEach(System.out::println);
|
4. 新日期时间API
4.1 旧API的问题
Java 8之前的日期时间API存在以下问题:
- 非线程安全 - Date和Calendar不是线程安全的
- 设计差 - 日期和时间类没有明确区分
- 时区处理麻烦
4.2 新API核心类
Java 8在java.time
包中提供了新的日期时间API:
- LocalDate - 日期(年月日)
- LocalTime - 时间(时分秒)
- LocalDateTime - 日期时间
- ZonedDateTime - 带时区的日期时间
- Instant - 时间戳
- Duration - 时间段
- Period - 日期段
- DateTimeFormatter - 日期时间格式化
4.3 基本使用
获取当前日期
1
| LocalDate today = LocalDate.now();
|
创建指定日期
1
| LocalDate date = LocalDate.of(2023, Month.NOVEMBER, 15);
|
日期运算
1 2
| LocalDate nextWeek = today.plusWeeks(1); LocalDate previousYear = today.minusYears(1);
|
日期比较
1
| boolean isAfter = today.isAfter(date);
|
格式化
1 2
| DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); String formattedDate = today.format(formatter);
|
解析
1
| LocalDate parsedDate = LocalDate.parse("2023-11-15", formatter);
|
5. 接口默认方法
5.1 什么是默认方法
Java 8允许在接口中定义具有实现的方法,称为默认方法,使用default
关键字修饰。
5.2 默认方法示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| interface Vehicle { void start(); default void stop() { System.out.println("Vehicle stopped"); } }
class Car implements Vehicle { @Override public void start() { System.out.println("Car started"); } }
public class Main { public static void main(String[] args) { Car car = new Car(); car.start(); car.stop(); } }
|
5.3 默认方法的作用
- 接口演进:可以向现有接口添加新方法而不破坏现有实现
- 多继承:解决Java中多继承的问题
- 提供通用功能:为所有实现类提供默认实现
5.4 默认方法冲突
当一个类实现多个接口,且这些接口有相同的默认方法时,需要解决冲突:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| interface A { default void show() { System.out.println("A"); } }
interface B { default void show() { System.out.println("B"); } }
class C implements A, B { @Override public void show() { A.super.show(); } }
|
6. 其他新特性
6.1 Optional类
用于避免NullPointerException:
1 2
| Optional<String> optional = Optional.ofNullable(getString()); optional.ifPresent(System.out::println);
|
6.2 方法引用
简化Lambda表达式:
1 2
| List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); names.forEach(System.out::println);
|
6.3 重复注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Repeatable(Authorities.class) @interface Authority { String value(); }
@interface Authorities { Authority[] value(); }
@Authority("admin") @Authority("user") public class User { }
|
7. 总结
Java 8通过引入Lambda表达式、Stream API、新日期时间API和接口默认方法等特性,极大地提升了Java语言的表达能力和开发效率。这些特性使得Java能够更好地适应现代编程需求,特别是在函数式编程和大数据处理方面。
掌握这些核心特性,可以帮助开发者编写更简洁、更易读、更高效的Java代码。
参考资料
- Java 8官方文档
- Java 8新特性教程
- Java 8实战
- Java 8 Stream API指南