Java 8引入了许多强大且实用的新特性,使得Java编程更加简洁和高效。本章将介绍其中一些最重要的特性。
8.1 Lambda表达式与函数式编程
Lambda表达式是Java 8引入的一种新语法,用于实现函数式编程。它允许你以更简洁的方式来表示匿名函数。
8.1.1 Lambda表达式的语法
Lambda表达式的基本语法如下:
(parameters) -> expression// 或者(parameters) -> { statements; }
示例
// 使用Lambda表达式实现Runnable接口Runnable runnable = () -> {for (int i = 0; i < 5; i++) {System.out.println("Hello from Lambda Runnable!");}};// 启动线程new Thread(runnable).start();
使用Lambda表达式替代匿名类
// 使用匿名类Comparator<String> comparator1 = new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return s1.compareTo(s2);}};// 使用Lambda表达式Comparator<String> comparator2 = (s1, s2) -> s1.compareTo(s2);// 使用Lambda表达式的Comparator进行排序List<String> list = Arrays.asList("apple", "banana", "cherry");Collections.sort(list, comparator2);System.out.println(list); // 输出:[apple, banana, cherry]
8.1.2 方法引用
方法引用是Lambda表达式的一种简洁语法,用于直接引用现有的方法或构造函数。
四种方法引用类型
- 静态方法引用:
ClassName::staticMethodName - 实例方法引用:
instance::instanceMethodName - 对象的任意实例的方法引用:
ClassName::instanceMethodName - 构造函数引用:
ClassName::new
示例
// 使用静态方法引用Function<String, Integer> parseInt = Integer::parseInt;Integer num = parseInt.apply("123");System.out.println(num); // 输出:123// 使用实例方法引用String str = "Hello, World!";Supplier<Integer> stringLength = str::length;System.out.println(stringLength.get()); // 输出:13// 使用构造函数引用Supplier<List<String>> listSupplier = ArrayList::new;List<String> list = listSupplier.get();list.add("apple");System.out.println(list); // 输出:[apple]
8.2 Stream API:数据流处理
Stream API允许我们以声明式的方式对集合数据进行操作,如过滤、排序和聚合。
8.2.1 创建Stream
Stream可以通过集合、数组或生成函数创建。
示例
// 从集合创建StreamList<String> list = Arrays.asList("apple", "banana", "cherry");Stream<String> stream1 = list.stream();// 从数组创建StreamString[] array = {"apple", "banana", "cherry"};Stream<String> stream2 = Arrays.stream(array);// 使用Stream生成函数Stream<String> stream3 = Stream.of("apple", "banana", "cherry");
8.2.2 常用操作
过滤(filter)
List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");Stream<String> filteredFruits = fruits.stream().filter(fruit -> fruit.startsWith("a"));filteredFruits.forEach(System.out::println); // 输出:apple
映射(map)
List<String> fruits = Arrays.asList("apple", "banana", "cherry");Stream<Integer> fruitLengths = fruits.stream().map(String::length);fruitLengths.forEach(System.out::println); // 输出:5, 6, 6
归约(reduce)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);int sum = numbers.stream().reduce(0, Integer::sum);System.out.println(sum); // 输出:15
聚合操作
List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");long count = fruits.stream().filter(fruit -> fruit.length() > 5).count();System.out.println(count); // 输出:2(banana和cherry)
8.3 Optional:优雅的空指针处理
Optional类是一个容器类,用于表示可能包含或不包含值的对象,通过显式地处理null值,避免空指针异常。
8.3.1 创建Optional对象
示例
// 创建空的OptionalOptional<String> empty = Optional.empty();// 使用非null值创建OptionalOptional<String> nonEmpty = Optional.of("Hello");// 使用可能为null的值创建OptionalOptional<String> nullable = Optional.ofNullable(null);
8.3.2 使用Optional对象
示例
Optional<String> optional = Optional.of("Hello, World!");// 检查是否有值if (optional.isPresent()) {System.out.println(optional.get());}// 使用ifPresent进行消费optional.ifPresent(value -> System.out.println("Value: " + value));// 设置默认值String defaultValue = optional.orElse("Default Value");System.out.println(defaultValue); // 输出:Hello, World!// 使用orElseGet提供默认值String defaultValue2 = optional.orElseGet(() -> "Default Value");System.out.println(defaultValue2); // 输出:Hello, World!// 使用orElseThrow抛出异常String value = optional.orElseThrow(() -> new RuntimeException("Value is not present"));System.out.println(value); // 输出:Hello, World!
8.3.3 Optional的链式操作
示例
Optional<String> optional = Optional.of("Hello, World!");// 链式操作optional.map(String::toUpperCase).filter(value -> value.startsWith("HELLO")).ifPresent(System.out::println); // 输出:HELLO, WORLD!
