首页 > 编程语言 > Java8 对list集合中的bigdecimal进行分组求和,均值,最大值,最小值

Java8 对list集合中的bigdecimal进行分组求和,均值,最大值,最小值

时间:2022-08-25 09:33:49浏览次数:91  
标签:mapper return bigdecimal list public add new Java8 BigDecimal

 

文章目录

 

需求中对数值进行求和的非常多,但java8对bigdecimal求和没有封装

通常求和我们都这么做:

    public static void main(String[] args) {
        List<BigDecimal> list = new ArrayList<>();
        list.add(BigDecimal.valueOf(1.1));
        list.add(BigDecimal.valueOf(1.2));
        list.add(BigDecimal.valueOf(1.3));
        list.add(BigDecimal.valueOf(1.4));
 
        BigDecimal decimal = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        System.out.println(decimal);
    }
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

带对象属性的:
//BigDecimal
BigDecimal total = list.stream().map(ReturnMoney::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

可不可以类似double求和
//mapToDouble,mapToInt,mapToLong
Double total = list.stream().mapToDouble(ReturnMoney::getAmount()).sum()//和;.max()//最大;.min()//最小;.average()//平均值

下面就对bigdecimal运算进行封装:

新建接口ToBigDecimalFunction

@FunctionalInterface
public interface ToBigDecimalFunction<T> {
    BigDecimal applyAsBigDecimal(T value);
}
 
  • 1
  • 2
  • 3
  • 4
  • 5

新建工具类CollectorsUtil

public class CollectorsUtil {
    static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet();

    private CollectorsUtil() {
    }

    @SuppressWarnings("unchecked")
    private static <I, R> Function<I, R> castingIdentity() {
        return i -> (R) i;
    }

    static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
        private final Supplier<A> supplier;
        private final BiConsumer<A, T> accumulator;
        private final BinaryOperator<A> combiner;
        private final Function<A, R> finisher;
        private final Set<Characteristics> characteristics;

        CollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner,
                      Function<A, R> finisher, Set<Characteristics> characteristics) {
            this.supplier = supplier;
            this.accumulator = accumulator;
            this.combiner = combiner;
            this.finisher = finisher;
            this.characteristics = characteristics;
        }

        CollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner,
                      Set<Characteristics> characteristics) {
            this(supplier, accumulator, combiner, castingIdentity(), characteristics);
        }

        @Override
        public BiConsumer<A, T> accumulator() {
            return accumulator;
        }

        @Override
        public Supplier<A> supplier() {
            return supplier;
        }

        @Override
        public BinaryOperator<A> combiner() {
            return combiner;
        }

        @Override
        public Function<A, R> finisher() {
            return finisher;
        }

        @Override
        public Set<Characteristics> characteristics() {
            return characteristics;
        }
    }

    //求和方法
    public static <T> Collector<T, ?, BigDecimal> summingBigDecimal(ToBigDecimalFunction<? super T> mapper) {
        return new CollectorImpl<>(
                () -> new BigDecimal[]{BigDecimal.ZERO},
                (a, t) -> { a[0] = a[0].add(mapper.applyAsBigDecimal(t)); },
                (a, b) -> { a[0] = a[0].add(b[0]) ; return a; },
                a -> a[0], CH_NOID);
    }

    //求最大值
    public static <T> Collector<T, ?, BigDecimal> maxBy(ToBigDecimalFunction<? super T> mapper) {
        return new CollectorImpl<>(
                () -> new BigDecimal[]{new BigDecimal(Long.MIN_VALUE)},
                (a, t) -> { a[0] = a[0].max(mapper.applyAsBigDecimal(t)); },
                (a, b) -> { a[0] = a[0].max(b[0]) ; return a; },
                a -> a[0], CH_NOID);
    }

    //求最小值
    public static <T> Collector<T, ?, BigDecimal> minBy(ToBigDecimalFunction<? super T> mapper) {
        return new CollectorImpl<>(
                () -> new BigDecimal[]{new BigDecimal(Long.MAX_VALUE)},
                (a, t) -> { a[0] = a[0].min(mapper.applyAsBigDecimal(t)); },
                (a, b) -> { a[0] = a[0].min(b[0]) ; return a; },
                a -> a[0], CH_NOID);
    }

    //求平均值
    public static <T> Collector<T, ?, BigDecimal> averagingBigDecimal(ToBigDecimalFunction<? super T> mapper, int newScale, int roundingMode) {
        return new CollectorImpl<>(
                () -> new BigDecimal[]{BigDecimal.ZERO,BigDecimal.ZERO},
                (a, t) -> { a[0] = a[0].add(mapper.applyAsBigDecimal(t)); a[1] = a[1].add(BigDecimal.ONE); },
                (a, b) -> { a[0] = a[0].add(b[0]) ; return a; },
                a -> a[0].divide(a[1],BigDecimal.ROUND_HALF_UP).setScale(newScale, roundingMode), CH_NOID);
    }
}
 
  • 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
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

实体类Person

@Data
class Person{
    private String sex;
    private Integer age;
    private BigDecimal score;

    public Person(String sex, Integer age, BigDecimal score) {
        this.sex = sex;
        this.age = age;
        this.score = score;
    }
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
List<Person> list = new ArrayList<>();
list.add(new Person("男",18,new BigDecimal(100)));
list.add(new Person("男",19,new BigDecimal(90)));
list.add(new Person("女",20,new BigDecimal(80)));
list.add(new Person("女",20,new BigDecimal(70)));
list.add(new Person("女",20,null));
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
//单条件筛选
//按照性别分组求分数总和
Map<String, BigDecimal> scoreCount = list.stream()
        .filter(t -> t.getScore() != null)
        .collect(Collectors.groupingBy(Person::getSex, CollectorsUtil.summingBigDecimal(Person::getScore)));
System.out.println("----按照性别分组求分数总和----");
scoreCount.forEach((k,v) -> System.out.println("key: " + k + " , " + "value: " + v));

//按照性别求分数平均值
Map<String, BigDecimal> scoreAvg = list.stream()
        .filter(t -> t.getScore() != null)
        .collect(Collectors.groupingBy(Person::getSex, CollectorsUtil.averagingBigDecimal(Person::getScore,2)));
System.out.println("----按照性别求分数平均值----");
scoreAvg.forEach((k,v) -> System.out.println("key: " + k + " , " + "value: " + v));


//多条件筛选
//多条件筛选分组属性
private static String fetchGroupKey(Person p) {
    return p.getAge() + "#" + p.getSex();
}

//按照性别年龄分组求分数总和
Map<String, BigDecimal> ageScoreCount = list.stream()
        .filter(t -> t.getScore() != null)
        .collect(Collectors.groupingBy(p -> fetchGroupKey(p), CollectorsUtil.summingBigDecimal(Person::getScore)));
System.out.println("----按照性别年龄分组求分数总和----");
ageScoreCount.forEach((k,v) -> System.out.println("key: " + k + " , " + "value: " + v));

//按照性别年龄分组求分数平均值
Map<String, BigDecimal> ageScoreAvg = list.stream()
        .filter(t -> t.getScore() != null)
        .collect(Collectors.groupingBy(p -> fetchGroupKey(p), CollectorsUtil.averagingBigDecimal(Person::getScore, 2)));
System.out.println("----按照性别年龄分组求分数平均值----");
ageScoreAvg.forEach((k,v) -> System.out.println("key: " + k + " , " + "value: " + v));
 
  • 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

public class CollectorsUtil {
static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet();

private CollectorsUtil() {
}

@SuppressWarnings("unchecked")
private static <I, R> Function<I, R> castingIdentity() {
    return i -> (R) i;
}

static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
    private final Supplier<A> supplier;
    private final BiConsumer<A, T> accumulator;
    private final BinaryOperator<A> combiner;
    private final Function<A, R> finisher;
    private final Set<Characteristics> characteristics;

    CollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner,
                  Function<A, R> finisher, Set<Characteristics> characteristics) {
        this.supplier = supplier;
        this.accumulator = accumulator;
        this.combiner = combiner;
        this.finisher = finisher;
        this.characteristics = characteristics;
    }

    CollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner,
                  Set<Characteristics> characteristics) {
        this(supplier, accumulator, combiner, castingIdentity(), characteristics);
    }

    @Override
    public BiConsumer<A, T> accumulator() {
        return accumulator;
    }

    @Override
    public Supplier<A> supplier() {
        return supplier;
    }

    @Override
    public BinaryOperator<A> combiner() {
        return combiner;
    }

    @Override
    public Function<A, R> finisher() {
        return finisher;
    }

    @Override
    public Set<Characteristics> characteristics() {
        return characteristics;
    }
}

//求和方法
public static <T> Collector<T, ?, BigDecimal> summingBigDecimal(ToBigDecimalFunction<? super T> mapper) {
    return new CollectorImpl<>(
            () -> new BigDecimal[]{BigDecimal.ZERO},
            (a, t) -> { a[0] = (ObjectUtil.isNotNull(a[0])?a[0]:BigDecimal.ZERO).add(ObjectUtil.isNotEmpty(mapper.applyAsBigDecimal(t))?mapper.applyAsBigDecimal(t):BigDecimal.ZERO);
            },
            (a, b) -> { a[0] = (ObjectUtil.isNotNull(a[0])?a[0]:BigDecimal.ZERO).add((ObjectUtil.isNotNull(b[0])?b[0]:BigDecimal.ZERO)) ; return a; },
            a -> a[0], CH_NOID);
}

//求最大值
public static <T> Collector<T, ?, BigDecimal> maxBy(ToBigDecimalFunction<? super T> mapper) {
    return new CollectorImpl<>(
            () -> new BigDecimal[]{new BigDecimal(Long.MIN_VALUE)},
            (a, t) -> { a[0] = (ObjectUtil.isNotNull(a[0])?a[0]:new BigDecimal(Long.MIN_VALUE)).max(ObjectUtil.isNotEmpty(mapper.applyAsBigDecimal(t))?mapper.applyAsBigDecimal(t):new BigDecimal(Long.MIN_VALUE)); },
            (a, b) -> { a[0] = (ObjectUtil.isNotNull(a[0])?a[0]:BigDecimal.ZERO).max((ObjectUtil.isNotNull(b[0])?b[0]:BigDecimal.ZERO)) ; return a; },
            a -> a[0], CH_NOID);
}

//求最小值
public static <T> Collector<T, ?, BigDecimal> minBy(ToBigDecimalFunction<? super T> mapper) {
    return new CollectorImpl<>(
            () -> new BigDecimal[]{new BigDecimal(Long.MAX_VALUE)},
            (a, t) -> { a[0] = a[0].min(mapper.applyAsBigDecimal(t)); },
            (a, b) -> { a[0] = a[0].min(b[0]) ; return a; },
            a -> a[0], CH_NOID);
}

//求平均值  null不计数
public static <T> Collector<T, ?, BigDecimal> averagingBigDecimal(ToBigDecimalFunction<? super T> mapper, int newScale, int roundingMode) {
    return new CollectorImpl<>(
            () -> new BigDecimal[]{BigDecimal.ZERO,BigDecimal.ZERO},
            (a, t) -> { a[0] = a[0].add(mapper.applyAsBigDecimal(t)); a[1] = a[1].add(BigDecimal.ONE); },
            (a, b) -> { a[0] = a[0].add(b[0]) ; return a; },
            a -> a[0].divide(a[1],BigDecimal.ROUND_HALF_UP).setScale(newScale, roundingMode), CH_NOID);
}
//求平均值 null计数
public static <T> Collector<T, ?, BigDecimal> averagingBigDecimalIncludsNull(ToBigDecimalFunction<? super T> mapper, int newScale, int roundingMode) {
    return new CollectorImpl<>(
            () -> new BigDecimal[]{BigDecimal.ZERO,BigDecimal.ZERO},
            (a, t) -> { a[0] = (ObjectUtil.isNotNull(a[0])?a[0]:BigDecimal.ZERO).add(ObjectUtil.isNotEmpty(mapper.applyAsBigDecimal(t))?mapper.applyAsBigDecimal(t):BigDecimal.ZERO);
            a[1] = a[1].add(BigDecimal.ONE);
            },
            (a, b) -> { a[0] = (ObjectUtil.isNotNull(a[0])?a[0]:BigDecimal.ZERO).add((ObjectUtil.isNotNull(b[0])?b[0]:BigDecimal.ZERO)) ; return a; },
            a -> a[0].divide(a[1],BigDecimal.ROUND_HALF_UP).setScale(newScale, roundingMode), CH_NOID);
}
 
  • 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
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101

}

 
  • 1

标签:mapper,return,bigdecimal,list,public,add,new,Java8,BigDecimal
From: https://www.cnblogs.com/tiancai/p/16623147.html

相关文章

  • List连环问
    List连环问List?List是一个接口,常见的实现类有ArrayList和LinkedListArrayList和LinkedList的区别?ArrayList的底层数据结构是数组,支持下标访问,查询数据快。默认初始......
  • ArrayList学习
    核心源码packagejava.util;importjava.util.function.Consumer;importjava.util.function.Predicate;importjava.util.function.UnaryOperator;publiccla......
  • Reid操作list、 Jedis操作set&sorted
    Reid操作list 3)列表类型list:linkedlist格式。支持重复元秦lpush/rpushlpop/rpop案例:@Testpublicvoidtest4(){Jedis......
  • pagehelper list数据处理后进行分页
    问题背景:PageHelper的分页只有在PageHelper.startPage(pageNum,pageSize)之后的数据库查询语句才起作用,原因是PageHelper的实现原理是在数据库查询过程中通过拦截器拦截处......
  • Java-List集合字段求和函数
    一、FunctionCustom通用求和函数使用示例二、求和函数修订记录版本是否发布2020-01-25v1.0是一、FunctionCustom通用求和函数使用示例特点:简化代码......
  • 常用类 .BigDecimal
    BigDecimal是精确存储,而double是近似值存储位置:java.math包中作用:精确计算浮点数创建方式:BigDecimalbd=newBigDecimal("1.0")方法:BigDecimaladd(BigDecimalbd)加......
  • CCGridPictureEditor与ListBox的冲突
    昨天发现在ide中,设计Listbox,由于Item多,需要上下滑动Listbox来完成设计,结果一滑动,整个ide就没反应了!刚才,才发现,原来是CCGridPictureEditor的问题,当设置RowType=rtSingleRow......
  • 初识ListView
    BaseAdapter:抽象类,实际开发中我们会继承这个类并且重写相关方法,用得最多的一个Adapter!ArrayAdapter:支持泛型操作,最简单的一个Adapter,只能展现一行文字~SimpleAdapter:同......
  • Java集合-List
    1.Collection集合1.1集合体系结构【记忆】集合类的特点​ 提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变集合类的体系图1.2Collection集合概......
  • Redis中set和list的区别有哪些
    list和set的区别:1、List和Set都是接口继承于Collection接口。2、最大的不同就是List是可以重复的。而Set是不能重复的。(注意:元素虽然无放入顺序,但是元素在set中的位置是......