业务中需要将一组数据分类后收集总和,原本可以使用Collectors.summingInt(),但是我们的数据源是BigDecimal类型的,而Java8原生只提供了summingInt、summingLong、summingDouble三种基础类型的方法。

于是就自己动手丰衣足食吧。。

自定义工具类

public class MyCollectors {

private MyCollectors() {

}

// public static Collector summingBigDecimal(Function super T, BigDecimal> mapper) {}

// BigDecimal 类型的集合求和

public static Collector summingBigDecimal(ToBigDecimalFunction super T> mapper) {

return new CollectorImpl<>(

() -> new BigDecimal[] { BigDecimal.ZERO },

(a, t) -> a[0] = a[0].add(mapper.applyAsInt(t)),

(a, b) -> {

a[0] = a[0].add(b[0]);

return a;

},

a -> a[0],

Collections.emptySet()

);

}

static class CollectorImpl implements Collector {

// 创建一个计算用的容器

private final Supplier supplier;

// 计算逻辑

private final BiConsumer accumulator;

// 合并逻辑

private final BinaryOperator combiner;

// 返回最终计算值

private final Function finisher;

// 空Set

private final Set characteristics;

CollectorImpl(Supplier supplier, BiConsumer accumulator, BinaryOperator combiner,

Function finisher, Set characteristics) {

this.supplier = supplier;

this.accumulator = accumulator;

this.combiner = combiner;

this.finisher = finisher;

this.characteristics = characteristics;

}

CollectorImpl(Supplier supplier, BiConsumer accumulator, BinaryOperator combiner,

Set characteristics) {

this(supplier, accumulator, combiner, castingIdentity(), characteristics);

}

@Override

public BiConsumer accumulator() {

return accumulator;

}

@Override

public Supplier supplier() {

return supplier;

}

@Override

public BinaryOperator combiner() {

return combiner;

}

@Override

public Function finisher() {

return finisher;

}

@Override

public Set characteristics() {

return characteristics;

}

}

@SuppressWarnings("unchecked")

private static Function castingIdentity() {

return i -> (R) i;

}

}

自定义函数式接口

@FunctionalInterface

public interface ToBigDecimalFunction {

BigDecimal applyAsInt(T value);

}

测试入口

public class AnswerApp {

public static void main(String[] args) {

List list = Lists.newArrayList();

for (int i = 0; i < 24; i++) {

list.add(BigDecimal.valueOf(i + 10.2121543));

}

// 方式1

BigDecimal sum = 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接口

import java.math.BigDecimal;

@FunctionalInterface

public interface ToBigDecimalFunction {

BigDecimal applyAsBigDecimal(T value);

}

第二步

创建工具类 实现接口

import java.math.BigDecimal;

import java.util.Collections;

import java.util.Set;

import java.util.function.BiConsumer;

import java.util.function.BinaryOperator;

import java.util.function.Function;

import java.util.function.Supplier;

import java.util.stream.Collector;

public class CollectorsUtil {

static final Set CH_NOID = Collections.emptySet();

private CollectorsUtil() {

}

@SuppressWarnings("unchecked")

private static Function castingIdentity() {

return i -> (R) i;

}

/**

* Simple implementation class for {@code Collector}.

*

* @param

* the type of elements to be collected

* @param

* the type of the result

*/

static class CollectorImpl implements Collector {

private final Supplier supplier;

private final BiConsumer accumulator;

private final BinaryOperator combiner;

private final Function finisher;

private final Set characteristics;

CollectorImpl(Supplier supplier, BiConsumer accumulator, BinaryOperator combiner,

Function finisher, Set characteristics) {

this.supplier = supplier;

this.accumulator = accumulator;

this.combiner = combiner;

this.finisher = finisher;

this.characteristics = characteristics;

}

CollectorImpl(Supplier supplier, BiConsumer accumulator, BinaryOperator combiner,

Set characteristics) {

this(supplier, accumulator, combiner, castingIdentity(), characteristics);

}

@Override

public BiConsumer accumulator() {

return accumulator;

}

@Override

public Supplier supplier() {

return supplier;

}

@Override

public BinaryOperator combiner() {

return combiner;

}

@Override

public Function finisher() {

return finisher;

}

@Override

public Set characteristics() {

return characteristics;

}

}

public static Collector summingBigDecimal(ToBigDecimalFunction super T> mapper) {

return new CollectorImpl<>(() -> new BigDecimal[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]);

return a;

}, a -> a[0], CH_NOID);

}

}

使用测试

import com.example.javademo.JavaDemoApplicationTests;

import com.example.javademo.pojo.Student;

import com.example.javademo.utils.DataUtils;

import org.junit.Test;

import java.math.BigDecimal;

import java.util.stream.Collectors;

public class TestBigDecimal extends JavaDemoApplicationTests {

@Test

public void testGroupByAfterBigdecimal(){

/*

自定义实现对分组后的集合,属性为bigdecmal进行相加

*/

System.out.println(DataUtils.getData().stream().collect(Collectors.groupingBy(Student::getSchool,CollectorsUtil.summingBigDecimal(Student::getMoney))));

//归约造作

BigDecimal reduce = DataUtils.getData().stream().map(Student::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);

System.out.println(reduce);

int sum = DataUtils.getData().stream().mapToInt(Student::getAge).sum();

System.out.println(sum);

}

}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

java 相加的函数_Java8 Collectors求和功能的自定义扩展操作相关推荐

  1. collectors 求和_Java8中Collectors求和功能的自定义扩展

    Apple iPhone 11 (A2223) 128GB 黑色 移动联通电信4G手机 双卡双待 4999元包邮 去购买 > 起因 业务中需要将一组数据分类后收集总和,原本可以使用Collect ...

  2. 用java实现combin函数_Java8的CompletableFuture进阶之道

    简介 作为Java 8 Concurrency API改进而引入,本文是CompletableFuture类的功能和用例的介绍.同时在Java 9 也有对CompletableFuture有一些改进, ...

  3. 用java实现combin函数_Java8的CompletableFuture

    Java8的CompletableFuture Java8提供了一种函数风格的异步和事件驱动编程模型CompletableFuture,该模型不同于以往Java版本,不会造成堵塞Blocking.过去 ...

  4. java查看so函数_java - 加入星火功能时,Eclipse不检测的Java main()函数 - SO中文参考 - www.soinside.com...

    我使用的Java测试Spark和使用Eclipse运行我的程序时遇到了一些问题. 测试代码如下: package projet1; import org.apache.log4j.Level; imp ...

  5. java 内置函数_java8 四大内置核心函数式接口

    其他补充接口: 一.Consumer:消费型接口(void accept(T t)) 来看一个简单得例子: 1 /** 2 * 消费型接口Consumer 3 */ 4 @Test 5 public ...

  6. 笔记整理1----Java语言基础(一)01 变量与数据类型+02 运算符与表达式+03 条件判断与循环语句+04 JAVA数组+05 函数与方法

    01 变量与数据类型+02 运算符与表达式+03 条件判断与循环语句+04 JAVA数组+05 函数与方法 第01天 java基础知识 今日内容介绍  Java概述.helloworld案例  工 ...

  7. java秃顶_【本人秃顶程序员】在Java中使用函数范式提高代码质量

    ←←←←←←←←←←←← 快!点关注 在一个范式和技术堆栈一直在变化的世界中,保持竞争力和提高生产力和质量的斗争有时候证明是一项挑战. 在本文中,我想首先展示一下函数编程(FP)的优势,特别是加强Ja ...

  8. Java基础系列-Collector和Collectors

    原创文章,转载请标注出处:<Java基础系列-Collector和Collectors> 一.概述 Collector是专门用来作为Stream的collect方法的参数的. public ...

  9. 用java实现combin函数_Java并发工具类CompletableFuture教程与示例

    Java 8带来了大量的新功能和增强功能,例如Lambda表达式,Streams,CompletableFutures等.在本文中,我将通过简单的示例向您详细说明CompletableFuture及其 ...

最新文章

  1. PlantCom:基于内参的宿主相关丰度定量分析揭示植物根系微生物组的微生物总量变化
  2. select语句for update---转载
  3. mysqld:表mysql.plugin不存在_99%测试工程师不知道的数据库知识|干货
  4. spring+websocket综合(springMVC+spring+MyBatis这是SSM框架和websocket集成技术)
  5. 详解TCP协议的服务特点以及连接建立与终止的过程(俗称三次握手四次挥手)
  6. 02 ARM11 时钟初始化后的跑马灯程序
  7. 不用鼠标,程序员编程竟能如此高效?
  8. 毕设题目:Matlab优化求解
  9. MySQL 高阶语句
  10. 决策树之CART 算法
  11. 【第十届“泰迪杯”数据挖掘挑战赛】C题:疫情背景下的周边游需求图谱分析 赛后总结、46页论文及代码
  12. 此时不应有 \Common
  13. matlab个版本介绍,matlab软件功能简要介绍及版本描述
  14. 浅析Kafka实时数据处理系统
  15. aruba无线ap认证服务器,【图片】Aruba家用无线控制器无线AP+AC方案分析选择【aruba吧】_百度贴吧...
  16. Eclipse软件使用教程
  17. FreeModbus快速入门指南
  18. AlertPay 简介
  19. Mac下的终端(terminal)常用命令
  20. python历史波动率_【BSM模型】用实际市场数据计算隐含波动率并验证波动率微笑...

热门文章

  1. 将python3.7降为3.5_python3.7降至3.5【python cookbook】python访问子字符串
  2. ppt复制切片器_这6个新手必学的PPT技能,让你效率提升10倍!套模板都比别人快...
  3. java项目大小_Java项目仅在调整窗口大小之后出现
  4. Python基础教程:连接列表的八种方法,你都知道吗?
  5. python读文件的三个方法read()、readline()、readlines()详解
  6. Python字节到大整数的打包与解包
  7. 200 行代码实现 2048 游戏
  8. android另开进程,android在一个app程序中,打开另一个app的方法
  9. 机房批量改计算机名计算机组,批量设置IP地址和计算机名
  10. 板子armv7_32怎么挂载windows文件夹?