Java 8 Collectors API
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论