Java 8 引入了一系列重要的新特性,极大地增强了 Java 语言的功能,尤其是在 函数式编程、流处理、日期时间 API 和 默认方法 等方面。这些新特性不仅提升了代码的可读性和简洁性,还改善了并发处理的性能。以下是 Java 8 主要新特性的详细说明。
1. Lambda 表达式
1.1 什么是 Lambda 表达式?
Lambda 表达式使得 Java 代码更加简洁,能够传递行为。它是 Java 函数式编程的核心,可以用来替代匿名内部类,减少代码量并增强可读性。
1.2 Lambda 基本语法
(parameters) -> expression
例如,使用 Lambda 表达式创建一个简单的线程:
Runnable r = () -> System.out.println("Hello from thread");
new Thread(r).start();
示例:
- 传统写法:
List<String> list = Arrays.asList("Java", "Python", "JavaScript");
Collections.sort(list, new Comparator<String>() {public int compare(String s1, String s2) {return s1.compareTo(s2);}
});
- 使用 Lambda 表达式:
List<String> list = Arrays.asList("Java", "Python", "JavaScript");
Collections.sort(list, (s1, s2) -> s1.compareTo(s2));
使用场景:
- 使用 Lambda 表达式可以替代匿名内部类,使得代码更加简洁和可读。
- 常用于 集合的遍历、排序、过滤等操作。
2. 函数式接口
2.1 什么是函数式接口?
一个接口如果只有 一个抽象方法,它就可以作为 函数式接口 使用,并可以用 @FunctionalInterface
注解进行标识。函数式接口可以直接用于 Lambda 表达式和方法引用。
@FunctionalInterface
interface MyFunction {void execute(); // 仅一个抽象方法
}
2.2 常用函数式接口
Java 8 提供了很多常用的内置函数式接口,例如:
- Runnable:无返回值的操作。
- Consumer:接受一个参数并执行操作,但没有返回值。
- Function<T, R>:接受一个参数并返回一个结果。
- Predicate:接受一个参数并返回一个布尔值。
- Supplier:无参数,返回一个结果。
3. Stream API(流式 API)
3.1 什么是 Stream?
Stream 是对集合的 函数式编程式操作,可以用于 过滤、映射、排序等操作,使得 Java 集合操作更加简洁。
3.2 Stream 操作分类
- 中间操作:返回一个新的 Stream,支持链式调用。常见的操作有:
filter()
、map()
、sorted()
、distinct()
等。 - 终止操作:触发计算并产生结果。常见的操作有:
collect()
、forEach()
、reduce()
等。
3.3 示例:
List<String> list = Arrays.asList("apple", "banana", "orange", "kiwi");// 使用 Stream 进行过滤和转换
List<String> result = list.stream().filter(s -> s.startsWith("a")).map(String::toUpperCase).collect(Collectors.toList());
System.out.println(result); // [APPLE]
使用场景:
- 数据处理和转换:Stream 使得数据处理更加直观和简洁,尤其是在处理集合(如
List
、Set
)时。 - 并行处理:Stream 可以轻松实现 并行处理,提高大数据集的处理效率。
4. 默认方法(Default Methods)
4.1 什么是默认方法?
默认方法是接口中可以定义有实现的方法。通过使用 default
关键字,接口可以提供 默认实现,从而避免修改现有接口时影响已有实现。
4.2 示例:
interface MyInterface {default void print() {System.out.println("Hello from MyInterface");}
}class MyClass implements MyInterface {// 无需实现 print() 方法,接口提供了默认实现
}public class Test {public static void main(String[] args) {MyClass obj = new MyClass();obj.print(); // 输出:Hello from MyInterface}
}
使用场景:
- 当接口需要在多个实现类中使用相同的默认方法时,使用默认方法可以避免在所有实现类中都重复实现该方法。
5. 新的日期时间 API(java.time)
5.1 引入新的日期时间 API
Java 8 引入了新的日期时间 API (java.time
),其中包括:
- LocalDate:表示日期(无时间)。
- LocalTime:表示时间(无日期)。
- LocalDateTime:表示日期和时间。
- ZonedDateTime:表示带时区的日期时间。
5.2 新 API 示例
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;public class DateTimeExample {public static void main(String[] args) {LocalDate date = LocalDate.now(); // 获取当前日期LocalTime time = LocalTime.now(); // 获取当前时间LocalDateTime dateTime = LocalDateTime.now(); // 获取当前日期和时间System.out.println("Current Date: " + date);System.out.println("Current Time: " + time);System.out.println("Current DateTime: " + dateTime);}
}
使用场景:
- 处理日期、时间和时区时使用新的
java.time
包,避免了旧 API(java.util.Date
和Calendar
)的一些不便之处,如线程不安全、可变性等问题。
6. Optional 类
6.1 什么是 Optional?
Optional
类是一个容器对象,用来表示可能为 null
的值,避免显式的空值检查。它主要通过 ifPresent()、orElse()、map() 等方法来处理 null
值。
6.2 示例:
import java.util.Optional;public class OptionalExample {public static void main(String[] args) {String name = "Java";Optional<String> optName = Optional.ofNullable(name); // 包装非 null 值// 如果值存在,打印optName.ifPresent(System.out::println); // Java// 如果值为空,提供默认值System.out.println(optName.orElse("Unknown")); // Java}
}
使用场景:
Optional
常用于方法返回值,表示该值可能为空,避免了显式的空值检查和NullPointerException
。
7. 方法引用(Method References)
7.1 什么是方法引用?
方法引用是 Lambda 表达式的一种简化形式,允许直接引用类的方法。可以用 Class::methodName
或 object::methodName
来引用方法。
7.2 示例:
import java.util.Arrays;
import java.util.List;public class MethodReferenceExample {public static void main(String[] args) {List<String> list = Arrays.asList("Java", "Python", "JavaScript");// 使用 Lambda 表达式list.forEach(s -> System.out.println(s));// 使用方法引用list.forEach(System.out::println);}
}
使用场景:
- 方法引用可以简化代码,尤其是在使用集合处理和流操作时,提升代码的简洁性。
8. 并行流(Parallel Streams)
8.1 什么是并行流?
Java 8 的 Stream API 支持并行流(Parallel Stream),它可以将流的操作自动分成多个任务并并行执行,利用多核 CPU 提高性能。
8.2 示例:
import java.util.Arrays;
import java.util.List;public class ParallelStreamExample {public static void main(String[] args) {List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);// 使用并行流进行计算int sum = list.parallelStream().mapToInt(Integer::intValue).sum();System.out.println(sum); // 输出 55}
}
使用场景:
- 适用于数据量大的操作,尤其是需要进行计算和聚合时,可以通过并行流充分利用多核处理器提高性能。
总结
Java 8 引入的多个特性,如 Lambda 表达式、Stream API、Optional、默认方法等,极大地提高了代码的简洁性和可维护性。它们使得 Java 在 函数式编程 和 并行计算 方面的能力得到了显著提升。