Stream流多字段求和、汇聚
实现方法
利用
1 |
Collectors.toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction) |
keyMapper :代表你最终想要获得的Map<Key, Value> 的Key valueMapper :代表你最终想要获得的Map<Key, Value> 的Value mergeFunction :表示碰到Key冲突是处理过程,{x, y}中x是已汇聚对象,y表示当前处理对象
对象类型数据处理
1 2 3 |
public static Map<String, Model> streamGroupSum(List<Model> datas){ return datas.stream().collect(Collectors.toMap(k -> k.getCode(), v -> v, (x, y) -> x.addCount().addAll(y))); } |
Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
@Data class Model{ private String code; private int count = 0 ; private Integer sum1; private Integer sum2; public Model(String code, Integer sum1, Integer sum2){ this .code = code; this .sum1 = sum1; this .sum2 = sum2; } public Model addCount(){ this .count++; return this ; }
public Model addAll(Model y){ return add(Model::setSum1, Model::getSum1, y) .add(Model::setSum2, Model::getSum2, y); } /** * 使用函数式编程,最终目的是为了求和,类似反射,具体使用方式请移步函数式编程 */ public Model add(BiConsumer<Model, Integer> set, Function<Model, Integer> get, Model y){ set.accept( this , get.apply( this ) + get.apply(y)); return this ; } } |
Map类型数据处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public static void main (String[] args) { List<Map<String, Object>> datas = getDatas(); streamMapSum(datas); } public static Map<Object, Map<String, Object>> streamMapSum (List<Map<String, Object>> datas) { return datas.stream() .collect(Collectors.toMap(k -> k.get( "name" ), v -> { v.put( "count" , 1 ); return v; } , (x, y) -> { x.put( "count" , ( int ) x.get( "count" ) + 1 ); x.put( "aaa" , ( int ) x.get( "aaa" ) + ( int ) y.get( "aaa" )); x.put( "bbb" , ( int ) x.get( "bbb" ) + ( int ) y.get( "bbb" )); x.put( "ccc" , ( int ) x.get( "ccc" ) + ( int ) y.get( "ccc" )); return x; /* //使用ofMap重构 return ofMap("name", x.get("name") , "count", (int) x.get("count") + 1 , "aaa", add(x, y, "aaa") , "bbb", add(x, y, "bbb") , "ccc", add(x, y, "ccc"));*/ } ) );
} public static int add (Map<String, Object> x, Map<String, Object> y, String key) { return ( int ) x.get(key) + ( int ) y.get(key); } public static Map<String, Object> ofMap (Object... objs) { System.out.println( "ofMap" ); Map<String, Object> map = new LinkedHashMap<>(); for ( int i = 0 ; i < objs.length; i = i + 2 ) { map.put(objs[i].toString(), objs[i + 1 ]); } return map; } public static List<Map<String, Object>> getDatas () { List<Map<String, Object>> list = new ArrayList<>(); list.add(ofMap( "name" , "张三" , "aaa" , 3 , "bbb" , 5 , "ccc" , 6 )); list.add(ofMap( "name" , "张三" , "aaa" , 8 , "bbb" , 51 , "ccc" , 521 )); list.add(ofMap( "name" , "李四" , "aaa" , 9 , "bbb" , 53 , "ccc" , 23 )); return list; } |
Stream分组求和使用笔记
话不多说,直接贴代码,分组使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class Foo { private int code; private int count; public Foo( int code, int count) { this .code = code; this .count = count; } public int getCode() { return code; } public void setCode( int code) { this .code = code; } public int getCount() { return count; } public void setCount( int count) { this .count = count; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public static void main(String[] args) { Foo foo1 = new Foo( 1 , 2 ); Foo foo2 = new Foo( 2 , 23 ); Foo foo3 = new Foo( 2 , 6 ); List<Foo> list = new ArrayList<>( 4 ); list.add(foo1); list.add(foo2); list.add(foo3); Map<Integer, List<Foo>> collect = list.stream().collect(Collectors.groupingBy(Foo::getCode)); List<Foo> list1 = collect.get( 1 ); List<Foo> list2 = collect.get( 2 ); list1.forEach(e -> System.out.println(e.getCode() + ":" + e.getCount())); System.out.println( "-----------这里是分界线-----------------------------" ); list2.forEach(e -> System.out.println(e.getCode() + ":" + e.getCount())); } |
输出结果:
1:2
-----------这里是分界线-----------------------------
2:23
2:6
分组求和使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public static void main(String[] args) { Foo foo1 = new Foo( 1 , 2 ); Foo foo2 = new Foo( 2 , 23 ); Foo foo3 = new Foo( 2 , 6 ); List<Foo> list = new ArrayList<>( 4 ); list.add(foo1); list.add(foo2); list.add(foo3); Map<Integer, IntSummaryStatistics> collect = list.stream().collect(Collectors.groupingBy(Foo::getCode, Collectors.summarizingInt(Foo::getCount))); IntSummaryStatistics statistics1 = collect.get( 1 ); IntSummaryStatistics statistics2 = collect.get( 2 ); System.out.println(statistics1.getSum()); System.out.println(statistics1.getAverage()); System.out.println(statistics1.getMax()); System.out.println(statistics1.getMin()); System.out.println(statistics1.getCount()); System.out.println(statistics2.getSum()); System.out.println(statistics2.getAverage()); System.out.println(statistics2.getMax()); System.out.println(statistics2.getMin()); System.out.println(statistics2.getCount()); } |
输出结果:
2
2.0
2
2
1
29
14.5
23
6
2
stream真的是相当的好用,Mark一下,欢迎大神在评论区留下你的Stream骚操作。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
原文链接:https://blog.csdn.net/weixin_42041388/article/details/119184542
查看更多关于Java8 Stream流多字段求和、汇聚的实例的详细内容...