我有一个发票模型类,其中包含购买日期和价格。
Class Invoice{
Date purchaseDate;
BigDecimal price;
//getters and setters
}
我得到发票 list ,其中包含一个月内销售的产品的所有发票:
List<Invoice> invoiceListForMonth;
我想获得每个月每一天的总销售额。
List<BigDecimal> dayWiseSales;
如何在 java 8 中使用 lambda 函数获取列表中的数据?
最佳答案
我想你需要这样的东西:
List<Invoice> invoiceListForMonth = new ArrayList<>();
//add some data
Map<LocalDate, BigDecimal> result =
invoiceListForMonth.stream()
.collect(Collectors.groupingBy(
Invoice::getPurchaseDate
)).entrySet().stream()//This will return a map of Map<LocalDateTime, List<Invoice>>
.collect(Collectors.toMap(Map.Entry::getKey, // to collect with the date
e -> e.getValue().stream().map(Invoice::getPrice) //and the sum of
.reduce(BigDecimal.ZERO, BigDecimal::add)) // prices
);
为了更好地理解它您可以将您的工作分为两步:
Map<LocalDateTime, List<Invoice>> grouping =
invoiceListForMonth.stream()
.collect(Collectors.groupingBy(Invoice::getPurchaseDate));
Map<LocalDate, BigDecimal> result = grouping.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().stream().map(Invoice::getPrice)
.reduce(BigDecimal.ZERO, BigDecimal::add))
);
请注意,我使用了 java.time
API 中的 LocalDate
,因为 Date
现在已经过时了,我不建议再使用它。
编辑
actually the Invoice class is used in multiple other places so I cannot change it to LocalDate. I tried to implement it using Date but my collection is grouped with date and time. I want to group using date only. Can you suggest something?
根据您的评论,您可以创建自己的方法,从日期中删除时间部分,这样您就可以像这样只比较日期部分:
public static Date getDateWithoutTime(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
然后你可以像这样调用 groupingBy
中的方法:
Map<Date, List<Invoice>> grouping =
invoiceListForMonth.stream()
.collect(Collectors.groupingBy(
p -> getDateWithoutTime(p.getPurchaseDate())
));
Map<Date, BigDecimal> result = grouping.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().stream().map(Invoice::getPrice)
.reduce(BigDecimal.ZERO, BigDecimal::add))
);
注意:我强烈不建议使用这个旧的 API,相反你可以移动到 java.time 这将对你有很大帮助。
关于java - 使用 Java 8 中的 lambda 函数获取 ArrayList 的总数,根据日期分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52065227/