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语法
基本语法:
| 12
 3
 
 | (parameters) -> expression或
 (parameters) -> { statements; }
 
 | 
2.3 Lambda示例
示例1:无参数
| 1
 | () -> System.out.println("Hello Lambda");
 | 
示例2:一个参数
| 1
 | str -> System.out.println(str);
 | 
示例3:多个参数
示例4:带返回值
| 12
 3
 4
 
 | (String s1, String s2) -> {System.out.println("Comparing " + s1 + " and " + s2);
 return s1.compareTo(s2);
 }
 
 | 
2.4 函数式接口
Lambda表达式需要函数式接口的支持。函数式接口是指仅包含一个抽象方法的接口。Java 8提供了@FunctionalInterface注解来标识函数式接口。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | @FunctionalInterfaceinterface 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
从集合创建
| 12
 
 | List<String> list = Arrays.asList("a", "b", "c");Stream<String> stream = list.stream();
 
 | 
从数组创建
| 12
 
 | 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);
 | 
日期运算
| 12
 
 | LocalDate nextWeek = today.plusWeeks(1);LocalDate previousYear = today.minusYears(1);
 
 | 
日期比较
| 1
 | boolean isAfter = today.isAfter(date);
 | 
格式化
| 12
 
 | 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 默认方法示例
| 12
 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 默认方法冲突
当一个类实现多个接口,且这些接口有相同的默认方法时,需要解决冲突:
| 12
 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:
| 12
 
 | Optional<String> optional = Optional.ofNullable(getString());optional.ifPresent(System.out::println);
 
 | 
6.2 方法引用
简化Lambda表达式:
| 12
 
 | List<String> names = Arrays.asList("Alice", "Bob", "Charlie");names.forEach(System.out::println);
 
 | 
6.3 重复注解
| 12
 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指南