嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议:
Stream是一个数据结构,它提供了一种方便的方式来处理和操作数据,Stream.collect() 方法则用于将 Stream 中的元素收集到指定的收集器(Collector)中,返回一个结果对象。收集器(Collector)可以是任何实现了 Collector 接口的对象,用于定义如何将 Stream 中的元素收集到结果对象中。而Collectors可以看作是收集器(Collector)的生产工厂,可以调用具体的静态方法返回一个具体的收集器。常用的如下:
Collectors类的toCollection()方法用于将Stream中的元素收集到新的集合中。这个方法的功能作用是接收一个输入流并产生一个输出结果,即把Stream中的元素收集到某种类型的集合中,这里的某类类型集合可由用户以lambda表达式来定义,如:
示例
- @Test
- public void test22(){
- Stream
stream = Stream.of("zhangsan", "lisi", "wangwu", "zhaoliu"); - HashSet
set = stream.collect(Collectors.toCollection(() -> new HashSet())); - System.out.println(set.toString());
- }
Collectors.toList() 用于将 Stream 中的元素收集到一个新的 List 中。这个方法返回一个 Collector 对象,该对象定义了如何将 Stream 中的元素收集到 List 中。
Collectors.toUnmodifiableList() 用于将 Stream 中的元素收集到一个新的不可修改的 List 中。这个方法返回一个 Collector 对象,该对象定义了如何将 Stream 中的元素收集到一个不可修改的 List 中。与Collectors#toList区别就是返回的 List 是不可修改的,无法被重新赋值或添加/删除元素。
Collectors.toSet() 用于将 Stream 中的元素收集到一个新的 Set 中。这个方法返回一个 Collector 对象,该对象定义了如何将 Stream 中的元素收集到 Set 中。
需要注意的是,Collectors.toSet() 方法返回的 Collector 对象可以处理任意类型的 Stream,包括泛型 Stream。这意味着您可以使用该方法将任何类型的元素收集到 Set 中。另外,由于 Set 本身不允许存在重复的元素,因此 Collectors.toSet() 方法会自动去重,只保留唯一的元素。
Collectors.toUnmodifiableSet()用于将 Stream 中的元素收集到一个新的、不可修改的 Set 中。这个方法返回一个 Collector 对象,该对象定义了如何将 Stream 中的元素收集到一个不可修改的 Set 中。
需要注意的是,由于返回的 Set 是不可修改的,因此不能添加或删除元素。这可以确保收集到的元素不会在后续操作中被修改。此外,与 Collectors.toList() 方法类似,toUnmodifiableSet() 方法也可以处理任意类型的 Stream,包括泛型 Stream。
Collectors.joining() 方法用于连接多个元素。该方法返回一个 Collector 实例,方便在流收集器上进行链式操作。Collectors.joining() 方法以遭遇元素的顺序拼接元素。我们可以传递自定义的拼接字符串、前缀和后缀。
- @Test
- public void test23() {
- Stream
stream = Stream.of("zhangsan", "lisi", "wangwu", "zhaoliu"); - String string = stream.collect(Collectors.joining("-"));
- System.out.println(string);//输出结果:zhangsan-lisi-wangwu-zhaoliu
- }
Collectors.counting()用于计算Stream中元素的数量。它会遍历输入的Stream,对每个元素进行计数,并返回一个Long类型的值,表示元素的数量。
- @Test
- public void test24() {
- Stream
stream = Stream.of("zhangsan", "lisi", "wangwu", "zhaoliu");; - Long count = stream.filter(item->item.startsWith("a")).collect(Collectors.counting());
- System.out.println(count);
- }
Collectors.minBy()用于在Stream中的元素上执行最小值计算操作。该方法方法接受一个比较器作为参数,并将该比较器用于Stream中的元素。它会计算每个元素的最小值,并返回一个包含最小值元素的Optional对,Optional对象包装了最小值元素。如果Stream为空,则返回的Optional对象为空(empty)。
- @Test
- public void test25() {
- Stream
stream = Stream.of(1, 6, 29, 45, 2); - Integer min = stream.collect(Collectors.minBy((v1, v2) -> {
- if (v1 > v2) {
- return 1;
- } else if (v1 < v2) {
- return -1;
- } else {
- return 0;
- }
- })).get();
- System.out.println(min);//输出结果为1
- }
Collectors.maxBy()用于将Stream中的元素进行比较并找出最大值。该方法接受一个比较函数作为参数,该比较函数定义了如何比较Stream中的元素。这个比较函数可以是自定义的,例如比较两个字符串的长度、比较两个日期的日期值等,通过比较操作可以找出Stream中最大的元素。
- @Test
- public void test26() {
- Stream
stream = Stream.of(1, 6, 29, 45, 2); - Integer min = stream.collect(Collectors.minBy((v1, v2) -> {
- if (v1 > v2) {
- return -1;
- } else if (v1 < v2) {
- return 1;
- } else {
- return 0;
- }
- })).get();
- System.out.println(min);//输出结果为45
- }
Collectors.summingInt()用于将Stream中的元素进行求和操作。该方法的功能作用是接受一个将对象映射为int的函数,并返回一个收集器,用于计算元素的和。在传递给普通的collect方法后,该收集器即执行所需的汇总操作,计算元素的和。
- @Test
- public void test26() {
- Stream
stream = Stream.of(10, 20, 30, 40, 50); - Integer sum = stream.collect(Collectors.summingInt(item -> item));
- System.out.println(sum);//输出结果为150
- }
Collectors.averagingInt()方法的功能作用是计算数值的平均数。它接受一个将对象映射为求和所需的int的函数,并返回一个收集器。在传递给普通的collect方法后,该收集器即执行所需的汇总操作,计算元素的平均值。
- @Test
- public void test27() {
- Stream
stream = Stream.of(2, 4, 6); - double sum = stream.collect(Collectors.averagingInt(item->item));
- System.out.println(sum);//输出结果为4.0
- }
Collectors.reducing()方法的功能作用是对Stream中的元素进行归约操作,将Stream中的元素聚合为单一的值。该方法接受一个BinaryOperator作为参数,用于指定如何将两个元素进行归约操作。
- @Test
- public void test28() {
- Stream
stream = Stream.of(2, 4, 6); - Integer sum = stream.collect(Collectors.reducing(Integer::sum)).get();
- System.out.println(sum);
- Stream
stream2 = Stream.of(1, 2, 3); - Optional
optional = stream2.collect(Collectors.reducing((v1, v2) -> v1 + v2)); - Integer sum2 = optional.get();
- System.out.println(sum2);
- }
Collectors.groupingBy()用于将Stream中的元素进行分组操作。具体来说,先通过传递一个分类函数作为参数,Collectors.groupingBy()方法可以将Stream中的元素按照该函数的返回值进行分组。这个分类函数接受一个元素作为输入,并返回一个用于分组的键。然后Collectors.groupingBy()方法返回一个Collector对象,该对象定义了如何将分组后的结果收集到一个Map中。默认情况下,它会收集每个分组的元素并返回一个Map,其中键是分类函数的返回值,值是对应的元素列表。
- @Test
- public void test29(){
- List
list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19)); - Map
> map = list.stream().collect(Collectors.groupingBy(item -> item.getName())); - System.out.println(map.toString());
- }
Collectors#groupingByConcurrent方法与Collectors#groupingBy方法功能类似,唯一有些区别就是,Collectors#groupingByConcurrent方法返回值是ConcurrentMap
- @Test
- public void test30(){
- List
list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19)); - ConcurrentMap
> concurrentMap = list.stream().collect(Collectors.groupingByConcurrent(item -> item.getName())); - System.out.println(concurrentMap.toString());
- }
Collectors.partitioningBy()用于将Stream中的元素进行分区操作。该方法的功能作用是根据给定的二元函数将Stream中的元素分成两个部分,并返回一个包含两个子列表的Map。
示例
根据姓名是否以z开头对姓名集合进行分区
- @Test
- public void test31(){
- Stream
stream = Stream.of("zhangsan", "lisi", "wangwu", "zhaoliu"); - Map
> map = stream.collect(Collectors.partitioningBy(item -> item.startsWith("z"))); - System.out.println(map.toString());//输出结果:{false=[lisi, wangwu], true=[zhangsan, zhaoliu]}
- }
Collectors.toMap()用于将Stream中的元素收集到Map中,它接受两个函数作为参数,一个用于映射键,另一个用于映射值。这些函数将应用于Stream中的每个元素,以生成对应的键和值。在收集元素时,如果存在重复的键,Collectors.toMap()方法的行为取决于是否提供了合并函数。如果提供了合并函数,该函数将用于处理重复键,以决定如何合并这些键的值。如果没有提供合并函数,那么在遇到重复键时,则会抛出IllegalStateException异常。
示例
把学生信息的List集合,转化为一个Map,key:学生姓名,value:学生年龄
- @Test
- public void test32(){
- List
list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19)); - Map
map = list.stream().collect(Collectors.toMap(item -> item.getName(), item -> item.getAge())); - System.out.println(map.toString());//输出结果:{lisi=19, zhangsan=18}
- List
list2 = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19),new Student("lisi", 20)); - Map
map2 = list2.stream().collect(Collectors.toMap(item -> item.getName(), item -> item.getAge(), (v1, v2) -> { - return v2;//如果key发生重复,则取重复对象的最后一个对象的val
- }));
- System.out.println(map2);
- }
Collectors.toUnmodifiableMap()用于将Stream中的元素收集到一个不可修改的Map中。它接受一个二元函数作为参数,用于将Stream中的元素映射为Map中的键值对。返回的Map是不可修改的,即无法添加、删除或修改其中的元素。这样可以保证Map的安全性,防止意外修改原始数据。除了这些特性,在用法上与Collectors#toMap相同
在使用Java的Stream流时,有一些容易踩坑的地方需要注意:
Java Stream的应用场景非常广泛,如果在实际的业务中以下类似的技术需求,那么都是可以使用Stream的相关能力助力业务实现:
总之,Java Stream可以应用于各种数据处理的场景,包括但不限于数据筛选与过滤、映射操作、排序操作、聚合操作、收集操作和遍历操作等。使用Stream可以简化代码、提高可读性和可维护性,并提高系统的性能和效率。