Java 8 引入了许多强大的新特性,其中流库(Stream API)和 Optional 类极大地简化了集合操作和空值处理。本文将深入探讨 filter、map、flatMap 以及 Optional 的概念和用法,并提供示例代码来展示其实际应用。
流库(Stream API)
流库提供了一种声明性方式来处理集合数据,支持过滤、映射、聚合等多种操作。流操作可以分为中间操作和终端操作。中间操作返回一个新的流,允许多个操作链式调用;终端操作触发流的处理并返回结果。
1. Filter
filter
是一个中间操作,用于从流中筛选出符合条件的元素。它接收一个谓词(Predicate)作为参数,返回一个由满足谓词条件的元素组成的新流。
示例:过滤出所有的偶数
java复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FilterExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenNumbers); // 输出: [2, 4, 6, 8, 10]
}
}
2. Map
map
是一个中间操作,用于将流中的每个元素应用一个函数,并将结果收集到一个新的流中。map
操作通常用于对象的转换和数据的提取。
示例:将字符串列表转换为其长度的列表
java复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("Java", "Stream", "API", "Filter", "Map");
List<Integer> lengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(lengths); // 输出: [4, 6, 3, 6, 3]
}
}
3. FlatMap
flatMap
是一个中间操作,与 map
类似,但它的映射函数会将每个元素转换为一个流,并将多个流合并成一个新的流。flatMap
常用于处理嵌套集合或多对多的映射关系。
示例:将单词列表拆分为字母列表
java复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlatMapExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("Java", "Stream", "API");
List<String> letters = words.stream()
.flatMap(word -> Arrays.stream(word.split("")))
.collect(Collectors.toList());
System.out.println(letters); // 输出: [J, a, v, a, S, t, r, e, a, m, A, P, I]
}
}
Optional 类
Optional
类是 Java 8 引入的一个特殊容器类,用于表示可能为空的值,避免显式的空检查和 NullPointerException
。
1. 创建 Optional
你可以使用 Optional.of
、Optional.ofNullable
或 Optional.empty
方法创建一个 Optional 对象。
java复制代码
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<String> nonEmptyOptional = Optional.of("Hello");
Optional<String> emptyOptional = Optional.empty();
Optional<String> nullableOptional = Optional.ofNullable(null);
System.out.println(nonEmptyOptional); // 输出: Optional[Hello]
System.out.println(emptyOptional); // 输出: Optional.empty
System.out.println(nullableOptional); // 输出: Optional.empty
}
}
2. 使用 Optional
Optional
提供了多种方法来处理可能为空的值,包括 isPresent
、ifPresent
、orElse
、orElseGet
和 orElseThrow
等。
示例:使用 Optional 处理可能为空的值
java复制代码
import java.util.Optional;
public class OptionalUsageExample {
public static void main(String[] args) {
Optional<String> optionalValue = Optional.of("Hello");
// 检查值是否存在
if (optionalValue.isPresent()) {
System.out.println(optionalValue.get()); // 输出: Hello
}
// 使用 ifPresent
optionalValue.ifPresent(value -> System.out.println(value)); // 输出: Hello
// 使用 orElse
String defaultValue = optionalValue.orElse("Default Value");
System.out.println(defaultValue); // 输出: Hello
// 使用 orElseGet
String valueFromSupplier = optionalValue.orElseGet(() -> "Value from Supplier");
System.out.println(valueFromSupplier); // 输出: Hello
// 使用 orElseThrow
try {
String valueOrException = optionalValue.orElseThrow(() -> new IllegalStateException("No value"));
System.out.println(valueOrException); // 输出: Hello
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
综合示例
下面是一个综合示例,展示了如何结合使用 Stream API 和 Optional 处理复杂的集合操作:
示例:处理嵌套的集合并处理空值
java复制代码
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class ComprehensiveExample {
public static void main(String[] args) {
List<List<String>> nestedList = Arrays.asList(
Arrays.asList("Java", "Stream"),
Arrays.asList("Optional", "Filter", null),
Arrays.asList("FlatMap", "Map")
);
List<String> processedList = nestedList.stream()
.flatMap(List::stream)
.map(word -> Optional.ofNullable(word).orElse("Empty"))
.filter(word -> !word.equals("Empty"))
.collect(Collectors.toList());
System.out.println(processedList); // 输出: [Java, Stream, Optional, Filter, FlatMap, Map]
}
}
总结
Java 8 的流库和 Optional 类为我们提供了强大且简洁的工具,用于处理集合数据和空值。通过 filter、map、flatMap 等中间操作,结合 Optional 类的方法,我们可以轻松地进行数据转换、过滤和空值处理,从而提高代码的可读性和安全性。希望本文对你理解和使用这些重要特性有所帮助。