Java8 Collectors求和功能的自定义扩展操作

网友投稿 256 2023-01-29

Java8 Collectors求和功能的自定义扩展操作

业务中需要将一组数据分类后收集总和,原本可以使用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));

http:// }, (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(){

/*

http:// 自定义实现对分组后的集合,属性为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);

}

}

http://

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:话费充值api优势(话费充值api优势在哪)
下一篇:话费充值API盈利(话费充值api 供货合作)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~