解决 坑: double 相乘的时候会出现问题(59.9 * 3 ) 

//  vo.setAmountsPayable(skus.stream().reduce(0.0, (x, y) -> x + (y.getPrice() * y.getQuantity()), Double::sum));
 double amountsPayable = skus.stream().map(item -> new BigDecimal(item.getPrice()).multiply(new BigDecimal(item.getQuantity()))).reduce(BigDecimal::add).get().setScale(2, BigDecimal.ROUND_UP).doubleValue();
double amountsPayable = skus.stream().map(item -> new BigDecimal(item.getPrice()).multiply(new BigDecimal(item.getQuantity()))).reduce(BigDecimal.ZERO,BigDecimal::add).setScale(2, BigDecimal.ROUND_UP).doubleValue();
vo.setAmountsPayable(amountsPayable);
public class Test {
    public static void main(String[] args) {
        List<Student> list1 = Arrays.asList(
                new Student(1, "t1", 1, BigDecimal.valueOf(1.5), 10d, "1"),
                new Student(2, "t2", 2, BigDecimal.valueOf(2.5), 20d, "2"),
                new Student(3, "t3", 2, BigDecimal.valueOf(3.5), 30d, "2"));


        //★★★★ 注意此写法:  .reduce((sum1, i) -> sum1 + i)

        // 新方法:可以用内建方法,也可以自己定义
        //Map和Reduce操作是函数式编程的核心操作,因为其功能,reduce 又被称为折叠操作。
        //SQL中类似 sum()、avg() 或者 count() 的聚集函数,实际上就是 reduce 操作,因为它们接收多个值并返回一个值。
        //流API定义的 reduceh() 函数可以接受lambda表达式,并对所有值进行合并。
        // IntStream这样的类有类似 average()、count()、sum() 的内建方法来做 reduce 操作,也有mapToLong()、mapToDouble() 方法来做转换。
        double bill = list1.stream()
                .map((i) -> i.price2 + 0.12 * i.price2)
                .reduce((sum1, i) -> sum1 + i)
                .get();
        // 为每个price2加上12%的税


        //mapToInt
        int sum1 = list1.stream()
                .mapToInt(p -> p.unit)
                .sum();
        System.out.println("--00->" + sum1);

        //mapToInt - nax 获取分享数
        Integer shareTatol = list1
                .stream()
                .mapToInt(Student::getId)
                .max()
                .orElse(0);
        System.out.println("--01->" + shareTatol);

        //null到时候,给默认值0.0
        Double reduce = list1.stream()
                .reduce(0.0, (x, y) -> x + (y.getPrice2() * y.getUnit()), Double::sum);
        System.out.println("--02->" + reduce);

        //
        Integer integer = list1.stream()
                .map(Student::getUnit)
                .max((x, y) -> Float.compare(x, y))
                .get();
        System.out.println("--03->" + integer);

        //从小到大分数排序:
        list1.stream()
                .map(Student::getUnit).sorted((x, y) -> Float.compare(x, y));
        double average = list1.stream()
                .map(Student::getPrice2).reduce(0.0, Double::sum) / list1.size();
        long count1 = list1.stream()
                .map(Student::getUnit).filter(r -> r > average).count();
        System.out.println("--035-高于平均值的有多少个:-->" + count1);

        //最大值,最小值,平均值
        // 为啥返回Optional? 如果stream为null怎么办, 这时候Optinal就很有意义了
        Optional<Student> mostCalorieDish = list1.stream().max(Comparator.comparingInt(Student::getUnit));
        Optional<Student> minCalorieDish = list1.stream().min(Comparator.comparingInt(Student::getUnit));
        Double avgCalories = list1.stream().collect(Collectors.averagingInt(Student::getUnit));
        System.out.println("--04->" + mostCalorieDish);
        System.out.println("--05->" + minCalorieDish);
        System.out.println("--06->" + avgCalories);

        // Collectors.maxBy 和 Collectors.minBy 来计算流中的最大或最小值。
        Optional<Student> maxDish = list1.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getUnit)));
        Optional<Student> minDish = list1.stream().collect(Collectors.minBy(Comparator.comparing(Student::getUnit)));
        System.out.println("--07->" + maxDish);
        System.out.println("--08->" + minDish);


        //BigDecimal::add方法1:
        BigDecimal amounts = list1.stream()
                .map(item -> item.price)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        amounts = amounts.setScale(1, BigDecimal.ROUND_UP);
        System.out.println("--09->" + amounts);

        BigDecimal amounts21 = list1.stream()
                .map(item -> item.price.multiply(BigDecimal.valueOf(item.unit)))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        amounts21 = amounts21.setScale(1, BigDecimal.ROUND_UP);
        System.out.println("--091->" + amounts21);

        //BigDecimal::add方法2:
        BigDecimal sum2 = list1.stream()
                .map(Student::getPrice)
                .reduce(BigDecimal::add)
                .get();
        sum2 = sum2.setScale(1, BigDecimal.ROUND_UP);
        System.out.println("--10->" + sum2);
        BigDecimal sum21 = list1.stream()
                .map(item -> item.price.multiply(BigDecimal.valueOf(item.unit)))
                .reduce(BigDecimal::add)
                .get();
        sum21 = sum21.setScale(1, BigDecimal.ROUND_UP);
        System.out.println("--101->" + sum21);


        list1.stream().mapToDouble(Student::getUnit).sum();//和
        list1.stream().mapToDouble(Student::getUnit).max();//最大
        list1.stream().mapToDouble(Student::getUnit).min();//最小
        list1.stream().mapToDouble(Student::getUnit).average();//平均值

        // intStream、LongStream 和 DoubleStream 等流的类中,有个非常有用的方法叫做 summaryStatistics() 。
        // 可以返回 IntSummaryStatistics、LongSummaryStatistics 或者 DoubleSummaryStatistic s,描述流中元素的各种摘要数据。
        //获取数字的个数、最小值、最大值、总和以及平均值  
//      IntSummaryStatistics summaryStatistics = list1.stream().mapToInt((x) -> x.getUnit()).summaryStatistics();
        IntSummaryStatistics summaryStatistics = list1.stream().collect(Collectors.summarizingInt(Student::getUnit));
        double average = summaryStatistics.getAverage();
        long count = summaryStatistics.getCount();
        int max = summaryStatistics.getMax();
        int min = summaryStatistics.getMin();
        long sum = summaryStatistics.getSum();
        System.out.println("count : " + count);
        System.out.println("max : " + max);
        System.out.println("min : " + min);
        System.out.println("Sum : " + sum);
        System.out.println("Average : " + average);

    }

    @Builder
    @Data
    @EqualsAndHashCode(callSuper = false)
    static class Student {
        int id;
        String name;
        Integer unit;
        BigDecimal price;
        double price2;
        String groupId;
    }
}