在Java中,Stream API是一个非常强大且灵活的工具,可以方便地对集合数据进行处理,包括数据的筛选、去重、分组、统计、排序等操作。本文将通过示例来展示如何使用Stream API按小时、天、周、月或年对数据进行分组和统计,并计算最大值、最小值、平均数和求和。
示例场景
假设我们有一个销售记录的列表,其中包含销售日期和销售金额。我们的任务是基于这个列表,进行各种统计分析。
定义销售记录类
首先,定义一个销售记录类 SaleRecord
,它包含销售日期和销售金额的属性。
import java.time.LocalDateTime;
public class SaleRecord {
private LocalDateTime date;
private double amount;
public SaleRecord(LocalDateTime date, double amount) {
this.date = date;
this.amount = amount;
}
public LocalDateTime getDate() {
return date;
}
public double getAmount() {
return amount;
}
}
声明销售记录列表
接下来,创建一组销售记录的示例数据:
import java.util.ArrayList;
import java.util.List;
public class SalesExample {
public static void main(String[] args) {
List<SaleRecord> sales = new ArrayList<>();
sales.add(new SaleRecord(LocalDateTime.of(2023, 3, 1, 10, 30), 200));
sales.add(new SaleRecord(LocalDateTime.of(2023, 3, 1, 11, 30), 150));
sales.add(new SaleRecord(LocalDateTime.of(2023, 3, 2, 10, 0), 300));
sales.add(new SaleRecord(LocalDateTime.of(2023, 3, 2, 14, 0), 250));
sales.add(new SaleRecord(LocalDateTime.of(2023, 3, 3, 9, 0), 100));
sales.add(new SaleRecord(LocalDateTime.of(2023, 3, 3, 15, 0), 450));
// 更多数据...
}
}
按日期分组和统计
以下是使用Stream进行数据的筛选、分组与统计的示例代码。我们以按天为例进行分组统计:
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.Map;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.*;
public class SalesExample {
public static void main(String[] args) {
List<SaleRecord> sales = createSaleRecords();
// 按天分组统计
Map<LocalDate, DoubleSummaryStatistics> dailyStatistics = sales.stream()
.collect(groupingBy(sale -> sale.getDate().toLocalDate(),
summarizingDouble(SaleRecord::getAmount)));
// 打印结果
dailyStatistics.forEach((date, stats) -> {
System.out.println("日期: " + date);
System.out.println("最大值: " + stats.getMax());
System.out.println("最小值: " + stats.getMin());
System.out.println("平均值: " + stats.getAverage());
System.out.println("总和: " + stats.getSum());
System.out.println("-------------------------------");
});
}
private static List<SaleRecord> createSaleRecords() {
// 生成销售记录
return // ... 添加代码来返回销售记录列表
}
}
按小时、周、月或年分组
可以使用相似的方法按小时、周、月或年进行分组。例如,按小时分组可以这样实现:
Map<String, DoubleSummaryStatistics> hourlyStatistics = sales.stream()
.collect(groupingBy(sale -> sale.getDate().getHour() + ":00",
summarizingDouble(SaleRecord::getAmount)));
排序操作
在统计后,您可能希望按某个指标进行排序,例如按总金额降序排列:
Map<LocalDate, DoubleSummaryStatistics> dailyStatistics = sales.stream()
.collect(groupingBy(sale -> sale.getDate().toLocalDate(),
summarizingDouble(SaleRecord::getAmount)));
List<Map.Entry<LocalDate, DoubleSummaryStatistics>> sortedEntries = dailyStatistics.entrySet().stream()
.sorted((entry1, entry2) -> Double.compare(entry2.getValue().getSum(), entry1.getValue().getSum()))
.collect(Collectors.toList());
sortedEntries.forEach(entry -> {
System.out.println("日期: " + entry.getKey() + ", 总金额: " + entry.getValue().getSum());
});
总结
本文介绍了如何利用Java Stream API对销售记录进行筛选、去重、分组、统计及排序的操作。通过这些示例,我们可以看到Stream API的便利性和强大功能,使得数据处理变得更加简单和优雅。你可以根据具体需求,灵活应用这些操作来处理各种数据。