本人详解
作者:王文峰,参加过 2020年度博客之星,《Java王大师王天师》
公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题
中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯
Java Stream API 详解:处理多种情况的数据过滤,映射,排序,去重,归约,查找,匹配,分组,分区,并行流
- 学习教程(传送门)
- Java Stream API 详解:处理多种情况的数据
- 简介
- Stream 的基本概念
- 创建 Stream
- 中间操作
- 过滤(Filter)
- 映射(Map)
- 排序(Sorted)
- 去重(Distinct)
- 终端操作
- 收集(Collect)
- 归约(Reduce)
- 查找(Find)
- 匹配(Match)
- 处理复杂情况
- 分组(Grouping)
- 分区(Partitioning)
- 平铺(FlatMap)
- 并行流(Parallel Streams)
- 结论
- 学习教程(传送门)
- 往期文章
Java Stream API 详解:处理多种情况的数据
简介
Java 8 引入了 Stream
API,这是一个用于处理集合的强大工具。Stream
提供了一种声明式的方式对数据进行过滤、映射、排序和聚合等操作。本文将详细介绍 Stream
的用法,并通过多个示例展示如何处理不同场景下的数据。
Stream 的基本概念
- 流(Stream):不是一种数据结构,它只是某种数据源(如集合、数组)上的数据处理管线。
- 中间操作(Intermediate Operations):返回一个新的流,可以链式调用。例如
filter
、map
、sorted
。 - 终端操作(Terminal Operations):触发流的执行并通常生成结果或副作用。一旦执行完,就不能再从该流中提取更多值。例如
forEach
、collect
、reduce
。 - 短路操作(Short-circuiting Operations):可以在不遍历所有元素的情况下产生结果。例如
anyMatch
、allMatch
、findFirst
。
创建 Stream
创建 Stream
有多种方式:
// 从集合创建
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> streamFromList = list.stream();
// 从数组创建
String[] array = {"apple", "banana", "orange"};
Stream<String> streamFromArray = Arrays.stream(array);
// 使用Stream.of()方法
Stream<String> streamOf = Stream.of("apple", "banana", "orange");
// 无限流
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);
中间操作
过滤(Filter)
// 只保留长度大于3的字符串
List<String> filtered = list.stream()
.filter(s -> s.length() > 3)
.collect(Collectors.toList());
映射(Map)
// 将每个字符串转换为大写
List<String> upperCased = list.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
排序(Sorted)
// 按字母顺序排序
List<String> sorted = list.stream()
.sorted()
.collect(Collectors.toList());
// 按字符串长度排序
List<String> lengthSorted = list.stream()
.sorted(Comparator.comparingInt(String::length))
.collect(Collectors.toList());
去重(Distinct)
// 去除重复元素
List<String> distinct = list.stream()
.distinct()
.collect(Collectors.toList());
终端操作
收集(Collect)
// 转换回列表
List<String> collectedToList = list.stream()
.collect(Collectors.toList());
// 聚合为一个字符串
String joined = list.stream()
.collect(Collectors.joining(", "));
归约(Reduce)
// 计算整数流的总和
Optional<Integer> sum = integerStream.reduce(Integer::sum);
// 或者使用二元运算符
int sumValue = integerStream.reduce(0, Integer::sum);
查找(Find)
// 查找第一个元素
Optional<String> first = list.stream()
.findFirst();
// 查找任意元素
Optional<String> any = list.stream()
.findAny();
匹配(Match)
// 检查是否所有元素都满足条件
boolean allMatch = list.stream()
.allMatch(s -> s.length() > 0);
// 检查是否有任意元素满足条件
boolean anyMatch = list.stream()
.anyMatch(s -> s.startsWith("a"));
// 检查没有元素满足条件
boolean noneMatch = list.stream()
.noneMatch(s -> s.isEmpty());
处理复杂情况
分组(Grouping)
// 按照字符串长度分组
Map<Integer, List<String>> groupedByLength = list.stream()
.collect(Collectors.groupingBy(String::length));
分区(Partitioning)
// 根据条件将流分区
Map<Boolean, List<String>> partitionedByLength = list.stream()
.collect(Collectors.partitioningBy(s -> s.length() > 4));
平铺(FlatMap)
当需要将每个元素映射到多个元素时,可以使用 flatMap
。
// 将每个字符串映射为字符流,然后合并为一个流
List<Character> characters = list.stream()
.flatMapToInt(String::chars)
.mapToObj(c -> (char) c)
.collect(Collectors.toList());
并行流(Parallel Streams)
对于大量数据的处理,可以考虑使用并行流来提高性能。
// 使用并行流进行过滤
List<String> parallelFiltered = list.parallelStream()
.filter(s -> s.length() > 3)
.collect(Collectors.toList());
请注意,并行流并不总是比串行流快,取决于具体的操作和数据量。
结论
Java Stream
API 提供了简洁且功能强大的接口来处理数据。通过组合中间操作和终端操作,我们可以轻松地实现复杂的数据处理逻辑。希望能帮助大家更好地理解和使用 Stream
API。