本人详解
作者:王文峰,参加过 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


Java Stream API 详解:处理多种情况的数据

Java Stream API 详解:处理多种情况的数据过滤,映射,排序,去重,归约,查找,匹配,分组,分区,并行流_微服务_02

简介

Java 8 引入了 Stream API,这是一个用于处理集合的强大工具。Stream 提供了一种声明式的方式对数据进行过滤、映射、排序和聚合等操作。本文将详细介绍 Stream 的用法,并通过多个示例展示如何处理不同场景下的数据。

Stream 的基本概念

  • 流(Stream):不是一种数据结构,它只是某种数据源(如集合、数组)上的数据处理管线。
  • 中间操作(Intermediate Operations):返回一个新的流,可以链式调用。例如 filtermapsorted
  • 终端操作(Terminal Operations):触发流的执行并通常生成结果或副作用。一旦执行完,就不能再从该流中提取更多值。例如 forEachcollectreduce
  • 短路操作(Short-circuiting Operations):可以在不遍历所有元素的情况下产生结果。例如 anyMatchallMatchfindFirst

创建 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。