动态参数+reduce累加stream

简介: 动态参数+reduce累加stream

通向面包的小路蜿蜒于劳动的沼泽之中,通向衣裳的小路从一块无花的土地中穿过,无论是通向面包的路还是通向衣裳的路,都是一段艰辛的历程。 ——福斯

今天有朋友问我,stream中如果要将一个User类中的usernameid收集起来变成两个list怎么写,我说可以使用peek函数

@Data
@AllArgsConstructor
static class User {
    private Long id;
    private Long groupId;
    private String username;
}

就像这样:

      // 用户列表
      List<User> userList = Stream.iterate(1L, i -> ++i).map(id -> new User(id, 999L, Faker.instance().name().username())).limit(10).collect(Collectors.toList());
      // 要收集起来的groupId
      List<Long> groupIds = new ArrayList<>(userList.size() * 2);
      // 要收集起来的username
      List<String> usernames = new ArrayList<>(userList.size() * 2);
      // 写死调用两个peek
      List<Long> userIds = userList.parallelStream().peek(user -> groupIds.add(user.getGroupId())).peek(user -> usernames.add(user.getUsername())).map(User::getId).collect(Collectors.toList());
System.out.println(userIds);
      System.out.println(groupIds);
      System.out.println(usernames);

然后运行结果:

然后它有问,如果他不知道有多少个,有可能有一个,也有可能两个怎么办

我就给他写了另外两种实现方式:

使用动态参数+reduce实现,以及List+reduce实现

/**
 * 封装peeks
 *
 * @param stream 流
 * @param peeks  操作
 * @return java.util.stream.Stream<T>
 * @author <achao1441470436@gmail.com>
 * @since 2021/10/24 21:12
 */
@SafeVarargs
public static <T> Stream<T> peek(Stream<T> stream, Consumer<T>... peeks) {
    return Stream.of(peeks).reduce(stream, Stream::peek, Stream::concat);
}
public static <T> Stream<T> peek(Stream<T> stream, List<Consumer<T>> peeks) {
    return peeks.stream().reduce(stream, Stream::peek, Stream::concat);
}

这两种,使用方式如下:

// 可以写死也可以动态
userIds = peek(userList.parallelStream(), user -> groupIds.add(user.getGroupId()), user -> usernames.add(user.getUsername())).map(User::getId).collect(Collectors.toList());
// 动态
List<Consumer<User>> peeks = Arrays.asList(user -> groupIds.add(user.getGroupId()), user -> usernames.add(user.getUsername()));
Stream<User> peek = peek(userList.stream(), peeks);
// 转成array
peek(userList.stream(), peeks.stream().<Consumer<User>>toArray(Consumer[]::new));
peek(userList.stream(), peeks.<Consumer<User>>toArray(new Consumer[0]));

这里原理就是用了reduce函数的累加特性,这个聚合操作:

Stream.of(peeks).reduce(stream, Stream::peek, Stream::concat);

相当于:

Stream<User> stream = userList.stream();
      for (Consumer<User> consumer : peeks) {
          stream = stream.peek(consumer);
      }

关于reduce我之前的博客也写过了,就不再赘述啦~

主要就是分享这种思路,多了一种写法而已

相关文章
|
3月前
|
数据处理
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
38 0
|
1月前
|
索引
|
3月前
|
JavaScript 前端开发
解一下操作数组的方法reduce,some,map,find
解一下操作数组的方法reduce,some,map,find
19 0
|
3月前
【stream】List根据某个字段求和
【stream】List根据某个字段求和
157 0
|
3月前
|
JavaScript 前端开发 索引
|
存储
Stream流中各阶段方法说明及组合示例
Stream流中各阶段方法说明及组合示例
96 1
|
3月前
|
分布式计算
MapReduce中的Map和Reduce函数分别是什么作用?
MapReduce中的Map和Reduce函数分别是什么作用?
127 0
|
3月前
|
Python
Python函数式编程,map(), filter() 和 reduce() 函数的作用是什么?
Python函数式编程,map(), filter() 和 reduce() 函数的作用是什么?
60 4
|
3月前
使用Lamda表达式、stream流遍历Map、list
使用Lamda表达式、stream流遍历Map、list
|
3月前
Stream流中将集合转成map,重复key处理,统计最大值,获取某个属性集合等12种最常用方法
Stream流中将集合转成map,重复key处理,统计最大值,获取某个属性集合等12种最常用方法
98 0