Stream中关于collect方法的介绍

本文深入探讨Java Stream API中的collect方法,包括两种不同形式的用法。通过实例展示了如何使用Collectors进行数组转换、数据分组统计及lambda表达式在Stream中的应用。同时,详细解析了第二种collect方法的参数作用及其在复杂数据转换场景下的实践。

在Stream 的API中可以查到有两种collect方法,分别是:

第一种:

<R, A> R collect(Collector<? super T, A, R> collector);

第二种:

<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator,
        BiConsumer<R, R> combiner);

对于第1个方法,我们主要是使用 Collectors(java.util.stream.Collectors)来进行各种 reduction 操作,下面举几个例子:

1.将数组组成字符串,注:Collectors.joining()有三个重载方法

String[] arr ={"aa","ccc","sss"};
System.out.println(Arrays.stream(arr).collect(joining()));
// aacccsss
System.out.println(Arrays.stream(arr).collect(joining("|")));
// aa|ccc|sss
System.out.println(Arrays.stream(arr).collect(joining(",","{","}")));
// {aa,ccc,sss}

2.将数组转为集合List

String[] arr ={"aa","ccc","sss"};
System.out.println(Arrays.stream(arr).collect(toList()));

// [aa, ccc, sss]

3.将list中的数据分组 并统计数量

public static class Person{
    private long id;
    private int age;
       private String name;

//   get/set
}

List<Person> list= Lists.newArrayList();
//假装list中已有许多条数据=-=
Map<Integer, Long> personGroups = list.stream().
               collect(Collectors.groupingBy(Person::getAge,counting()));
// 这样我们就得到了一个 以年龄为key,以这个年龄的人数为value的map了

上面应该是几个比较常用的对第一个collect方法的使用了。下面着重写一下对第二collect个方法的使用过程。

对于函数

<R> R collect(Supplier<R> supplier,
                  BiConsumer<R, ? super T> accumulator,
                  BiConsumer<R, R> combiner);

来说,参数supplier 是一个生成目标类型实例的方法,代表着目标容器是什么;accumulator是将操作的目标数据填充到supplier 生成的目标类型实例中去的方法,代表着如何将元素添加到容器中;而combiner是将多个supplier 生成的实例整合到一起的方法,代表着规约操作,将多个结果合并。

如上面的保存有多个Person实例的list来说,假如我们需要将这个list做一个转变,变为以id为key,value为person的Map的话,那就可以使用这个方法了:

Map<Long,Person> personMap =list.stream().collect(Maps::newHashMap,                                                                 
(map,p)>map.put(p.getId(),p),Map::putAll);                                      

注:lambda表达式的应用在Stream中很重要的。

上面的双冒号运算符所在的表达式转化一下就可以得到:

Map<Long,Person> personMap = list.stream().collect(() -> new HashMap<>(), 
                                 (map ,p) ->map.put(p.getId(),p),(m ,n) -> m.putAll(n));

 

### `collect` 方法的作用与使用方式 `collect` 是 Java Stream API 中的终端操作方法,用于将流中的元素收集并汇总为一个结果容器。该方法通常用于将流转换为集合、字符串、统计信息等结构化数据形式,适用于数据归约、分组、映射、聚合等多种处理场景[^3]。 `collect` 方法接受一个 `Collector` 接口的实现作为参数,通过定义收集策略(如累加、合并、结束操作等)来完成数据的最终处理。Java 提供了 `Collectors` 工具类,内置了多种常用的收集器实现,如 `toList`、`toSet`、`toMap`、`groupingBy` 等,便于开发者快速构建复杂的收集逻辑[^2]。 #### 常见使用方式 ##### 收集为列表 ```java List<String> names = people.stream() .map(Person::getName) .collect(Collectors.toList()); ``` 该方式将流中的元素收集为一个 `List`,适用于需要顺序存储和访问的场景[^3]。 ##### 收集为集合 ```java Set<String> uniqueNames = people.stream() .map(Person::getName) .collect(Collectors.toSet()); ``` 用于去重操作,将流元素收集为一个 `Set`,确保元素唯一性[^3]。 ##### 收集为映射表 ```java Map<Long, Person> personMap = people.stream() .collect(Collectors.toMap(Person::getId, person -> person)); ``` 将流元素转换为键值对形式的 `Map`,适用于需要快速查找的场景。注意,键冲突时需提供合并函数处理[^3]。 ##### 分组收集 ```java Map<Long, List<Person>> groupedById = people.stream() .collect(Collectors.groupingBy(Person::getId)); ``` 根据指定键对流元素进行分组,结果为一个 `Map`,键为分组依据,值为对应分组下的元素列表[^3]。 ##### 多级分组 ```java Map<Long, Map<String, List<Person>>> groupedByLevel = people.stream() .collect(Collectors.groupingBy(Person::getId, Collectors.groupingBy(Person::getGender))); ``` 支持嵌套分组,按多个条件对元素进行层级划分[^3]。 ##### 统计与聚合 ```java Double averageAge = people.stream() .collect(Collectors.averagingInt(Person::getAge)); ``` 用于计算平均值、总和、最大值等统计信息,适用于数据分析场景。 ##### 自定义收集器 ```java String joinedNames = people.stream() .map(Person::getName) .collect(Collectors.reducing((name1, name2) -> name1 + ", " + name2)) .orElse(""); ``` 结合 `reducing` 或自定义 `Collector` 实现特定的聚合逻辑,增强数据处理灵活性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值