Java8 Collectors求和功能的自定义扩展操作
业务中需要将一组数据分类后收集总和,原本可以使用Collectors.summingInt(),但是我们的数据源是BigDecimal类型的,而Java8原生只提供了summingInt、summingLong、summingDouble三种基础类型的方法。
于是就自己动手丰衣足食吧。。
自定义工具类
publicclassMyCollectors{ privateMyCollectors(){ } //publicstaticCollector summingBigDecimal(Functionmapper){} //BigDecimal类型的集合求和 publicstatic Collector summingBigDecimal(ToBigDecimalFunctionmapper){ returnnewCollectorImpl<>( ()->newBigDecimal[]{BigDecimal.ZERO}, (a,t)->a[0]=a[0].add(mapper.applyAsInt(t)), (a,b)->{ a[0]=a[0].add(b[0]); returna; }, a->a[0], Collections.emptySet() ); } staticclassCollectorImpl implementsCollector { //创建一个计算用的容器 privatefinalSuppliersupplier; //计算逻辑 privatefinalBiConsumeraccumulator; //合并逻辑 privatefinalBinaryOperatorcombiner; //返回最终计算值 privatefinalFunctionfinisher; //空Set privatefinalSet characteristics; CollectorImpl(Suppliersupplier,BiConsumeraccumulator,BinaryOperatorcombiner, Functionfinisher,Set characteristics){ this.supplier=supplier; this.accumulator=accumulator; this.combiner=combiner; this.finisher=finisher; this.characteristics=characteristics; } CollectorImpl(Suppliersupplier,BiConsumeraccumulator,BinaryOperatorcombiner, Set characteristics){ this(supplier,accumulator,combiner,castingIdentity(),characteristics); } @Override publicBiConsumeraccumulator(){ returnaccumulator; } @Override publicSuppliersupplier(){ returnsupplier; } @Override publicBinaryOperatorcombiner(){ returncombiner; } @Override publicFunctionfinisher(){ returnfinisher; } @Override publicSet characteristics(){ returncharacteristics; } } @SuppressWarnings("unchecked") privatestaticFunctioncastingIdentity(){ returni->(R)i; } }
自定义函数式接口
@FunctionalInterface publicinterfaceToBigDecimalFunction{ BigDecimalapplyAsInt(Tvalue); }
测试入口
publicclassAnswerApp{ publicstaticvoidmain(String[]args){ Listlist=Lists.newArrayList(); for(inti=0;i<24;i++){ list.add(BigDecimal.valueOf(i+10.2121543)); } //方式1 BigDecimalsum=list.stream().collect(MyCollectors.summingBigDecimal(e->e)); System.out.println(sum.doubleValue()); //方式2 Optional reduce=list.stream().reduce(BigDecimal::add); System.out.println(reduce.orElse(BigDecimal.valueOf(0))); } } //OUTPUT:521.0917032
补充:Collectors扩展接口实现BigDecimal的相加
第一步
创建ToBigDecimalFunction接口
importjava.math.BigDecimal; @FunctionalInterface publicinterfaceToBigDecimalFunction{ BigDecimalapplyAsBigDecimal(Tvalue); }
第二步
创建工具类实现接口
importjava.math.BigDecimal; importjava.util.Collections; importjava.util.Set; importjava.util.function.BiConsumer; importjava.util.function.BinaryOperator; importjava.util.function.Function; importjava.util.function.Supplier; importjava.util.stream.Collector; publicclassCollectorsUtil{ staticfinalSetCH_NOID=Collections.emptySet(); privateCollectorsUtil(){ } @SuppressWarnings("unchecked") privatestaticFunctioncastingIdentity(){ returni->(R)i; } /** *Simpleimplementationclassfor{@codeCollector}. * *@param *thetypeofelementstobecollected *@param *thetypeoftheresult */ staticclassCollectorImpl implementsCollector { privatefinalSuppliersupplier; privatefinalBiConsumeraccumulator; privatefinalBinaryOperatorcombiner; privatefinalFunctionfinisher; privatefinalSet characteristics; CollectorImpl(Suppliersupplier,BiConsumeraccumulator,BinaryOperatorcombiner, Functionfinisher,Set characteristics){ this.supplier=supplier; this.accumulator=accumulator; this.combiner=combiner; this.finisher=finisher; this.characteristics=characteristics; } CollectorImpl(Suppliersupplier,BiConsumeraccumulator,BinaryOperatorcombiner, Set characteristics){ this(supplier,accumulator,combiner,castingIdentity(),characteristics); } @Override publicBiConsumeraccumulator(){ returnaccumulator; } @Override publicSuppliersupplier(){ returnsupplier; } @Override publicBinaryOperatorcombiner(){ returncombiner; } @Override publicFunctionfinisher(){ returnfinisher; } @Override publicSet characteristics(){ returncharacteristics; } } publicstatic Collector summingBigDecimal(ToBigDecimalFunctionmapper){ returnnewCollectorImpl<>(()->newBigDecimal[1],(a,t)->{ if(a[0]==null){ a[0]=BigDecimal.ZERO; } a[0]=a[0].add(mapper.applyAsBigDecimal(t)); },(a,b)->{ a[0]=a[0].add(b[0]); returna; },a->a[0],CH_NOID); } }
使用测试
importcom.example.javademo.JavaDemoApplicationTests; importcom.example.javademo.pojo.Student; importcom.example.javademo.utils.DataUtils; importorg.junit.Test; importjava.math.BigDecimal; importjava.util.stream.Collectors; publicclassTestBigDecimalextendsJavaDemoApplicationTests{ @Test publicvoidtestGroupByAfterBigdecimal(){ /* 自定义实现对分组后的集合,属性为bigdecmal进行相加 */ System.out.println(DataUtils.getData().stream().collect(Collectors.groupingBy(Student::getSchool,CollectorsUtil.summingBigDecimal(Student::getMoney)))); //归约造作 BigDecimalreduce=DataUtils.getData().stream().map(Student::getMoney).reduce(BigDecimal.ZERO,BigDecimal::add); System.out.println(reduce); intsum=DataUtils.getData().stream().mapToInt(Student::getAge).sum(); System.out.println(sum); } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。