Java 提效神器 Stream 的冷门技巧( 三 )

newArrayList().stream().collect(Collectors.groupingBy(Person::getType, HashMap::new, Collectors.toList()));//因为对值有了操作,因此我可以更加灵活的对值进行转换Lists.newArrayList().stream().collect(Collectors.groupingBy(Person::getType, HashMap::new, Collectors.mapping(Person::getName,Collectors.toSet())));// 还有一种比较简单的使用方式 只需要传递一个参数按照key来划分Map> personsByAge = persons.stream().collect(Collectors.groupingBy(p -> p.age));4.reducing()reducing是针对单个值的收集,其返回结果不是集合家族的类型,而是单一的实体类T
容器: boxSupplier(identity),这里包裹用的是一个长度为1的Object[]数组,至于原因自然是不可变类型的锅
加入容器操作: a[0] = op.apply(a[0], t)
多容器合并: a[0] = op.apply(a[0], b[0]); return a;
聚合后的结果操作: 结果自然是Object[0]所包裹的数据a -> a[0]
优化操作状态字段: CH_NOID
public static <T> Collector<T, ?, T> reducing(T identity, BinaryOperator<T> op) { return new CollectorImpl<>( boxSupplier(identity),(a, t) -> { a[0] = op.apply(a[0], t); },(a, b) -> { a[0] = op.apply(a[0], b[0]); return a; },a -> a[0],CH_NOID);}简单来说这个地方做的事情和 reduce 是一样的 , 第一个 id 传入的就是 reduce 的初始值 , 只是他把它包装成一个 长度为1的数组了 。
//原生操作final Integer[] integers = Lists.newArrayList(1, 2, 3, 4, 5).stream().collect(() -> new Integer[]{0}, (a, x) -> a[0] += x, (a1, a2) -> a1[0] += a2[0]);//reducing操作final Integer collect = Lists.newArrayList(1, 2, 3, 4, 5).stream().collect(Collectors.reducing(0, Integer::sum));//当然Stream也提供了reduce操作final Integer collect = Lists.newArrayList(1, 2, 3, 4, 5).stream().reduce(0, Integer::sum)
【Java 提效神器 Stream 的冷门技巧】


推荐阅读