Java 8 Collectors API

发布于 2025-02-26 02:23:44 字数 5457 浏览 4 评论 0

Stream.collect() 是 Java 8 的 Stream API 的终端方法之一。借助该方法,我们可以将 Stream 实例中的元素重新打包为其他格式的数据,或执行元素拼接等操作。

其中 Stream.collect() 方法的操作策略是通过 java.util.stream.Collector 接口实现,而所有预定义的实现都可以在 java.util.stream.Collectors 类中找到。

Collectors.toList()

该收集器用于将所有 Stream 元素收集到 List 实例中:

List<String> result = Stream.of("a", "c", "b")
  .collect(Collectors.toList());
result.forEach(System.out::println); // a c b

该收集器无法指定任何特定类型的 List 实现类。如果要指定某个 List 实现类,则需要使用 Collectors.toCollection 方法:

List<String> result = Stream.of("a", "c", "b")
  .collect(Collectors.toCollection(ArrayList::new));
result.forEach(System.out::println); // a c b

Collectors.toSet()

该收集器用于将所有 Stream 元素收集到 Set 实例中:

Set<String> result = Stream.of("a", "c", "b", "a")
  .collect(Collectors.toSet());
result.forEach(System.out::println); // a b c

该收集器无法指定任何特定类型的 Set 实现。如果要指定某个 Set 实现类,则需要使用 Collectors.toCollection 方法:

Set<String> result = Stream.of("a", "c", "b", "a")
  .collect(Collectors.toCollection(HashSet::new));
result.forEach(System.out::println); // a b c

Collectors.toCollection()

该收集器用于指定特定的集合实现类型:

List<String> result = Stream.of("a", "c", "b")
  .collect(Collectors.toCollection(LinkedList::new));
result.forEach(System.out::println); // a c b

Collectors.toMap()

该收集器用于将所有 Stream 元素收集到 Map 实例中:

Map<String, Integer> result = Stream.of("a", "cde", "bc")
  .collect(Collectors.toMap(Function.identity(), String::length));
result.forEach((k, v) -> System.out.println(String.format("key=%s, value=%d", k, v)));
// key=bc, value=2
// key=a, value=1
// key=cde, value=3

上面的方法如果遇到重复 key,则会抛出 java.lang.IllegalStateException 异常,但我们可以通过 Collectors.toMap() 的另一个重载方法避免这种情况:

Map<String, Integer> result = Stream.of("a", "cde", "bc", "a")
  .collect(Collectors.toMap(
    Function.identity(), String::length, (item, identicalItem) -> item));
result.forEach((k, v) -> System.out.println(String.format("key=%s, value=%d", k, v)));
// key=bc, value=2
// key=a, value=1
// key=cde, value=3

Collectors.collectingAndThen()

这是一个特殊的收集器,允许在收集结束后立即对结果执行其他操作。比如将 Stream 元素收集到 List 中,然后将结果转换为不可变的 List 对象 com.google.common.collect.ImmutableList

List<String> result = Stream.of("a", "c", "b")
  .collect(Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf));
result.forEach(System.out::println); // a b c

Collectors.joining()

该收集器是一个连接收集器,可用于连接 Stream<String> 元素:

String result = Stream.of("a", "c", "b").collect(Collectors.joining()); // acb

还可以指定自定义分隔符:

String result = Stream.of("a", "c", "b").collect(Collectors.joining(" ")); // a c b

此外,还可以指定前缀、后缀:

String result = Stream.of("a", "c", "b")
  .collect(Collectors.joining(" ", "---PRE---\n", "\n---POST---"));
// ---PRE---
// a c b
// ---POST---

Collectors.counting()

该收集器是一个简单的计数收集器,用于简单地计算所有 Stream 元素的总个数:

long result = Stream.of("a", "c", "b").collect(Collectors.counting()); // 3

Collectors.summarizingDouble/Long/Int()

这类收集器返回的是一个特殊的类,其中包含有关提取的元素流中的数字数据的统计信息:

IntSummaryStatistics result = Stream.of("a", "c", "b")
.collect(Collectors.summarizingInt(String::length));
// IntSummaryStatistics{count=3, sum=3, min=1, average=1.000000, max=1}

Collectors.averagingDouble/Long/Int()

这类收集器只返回提取的元素的平均值:

Double result = Stream.of("a", "c", "b")
  .collect(Collectors.averagingInt(String::length)); // 1.0

Collectors.summingDouble/Long/Int()

这类收集器只返回提取的元素的总和:

int result = Stream.of("a", "c11", "b")
  .collect(Collectors.summingInt(String::length)); // 5

Collectors.maxBy()/minBy()

这类收集器会根据提供的比较器实例,返回 Stream 的最大/最小元素:

Optional<String> result = Stream.of("a", "c11", "b")
  .collect(Collectors.maxBy(Comparator.naturalOrder())); // Optional[c11]

Collectors.groupingBy()

该收集器用于按某些属性对对象进行分组,并将结果存储在 Map 实例中:

Map<Integer, Set<String>> result = Stream.of("a", "c11", "b")
  .collect(Collectors.groupingBy(String::length, Collectors.toSet())); // {1=[a, b], 3=[c11]}

Collectors.partitioningBy()

该收集器是 groupingBy 的一个特例,它接受一个 Predicate 实例,并将 Stream 元素收集到一个 Map 实例中,该实例将布尔值存储为 key,将集合存储为 value。key 为 true 的值是符合 Predicate 的集合;而 key 为 false 的值则是不符合 Predicate 的集合:

Map<Boolean, List<String>> result = Stream.of("a", "c11", "b")
  .collect(Collectors.partitioningBy(s -> s.length() > 2)); // {false=[a, b], true=[c11]}

自定义收集器

Collector<String, ?, LinkedList<String>> toLinkedList =
  Collector.of(LinkedList::new, LinkedList::add,
    (first, second) -> {
      first.addAll(second);
      return first;
});

LinkedList<String> linkedList = Stream.of("a", "c", "b").collect(toLinkedList);
linkedList.forEach(System.out::println);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

十二

暂无简介

文章
评论
27 人气
更多

推荐作者

闻呓

文章 0 评论 0

深府石板幽径

文章 0 评论 0

mabiao

文章 0 评论 0

枕花眠

文章 0 评论 0

qq_CrTt6n

文章 0 评论 0

红颜悴

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文