解决 坑: 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;
}
}