我从数据库收到一些结果集,并将每一行存储为DbRow
类型的对象,这是该类:
public class DbRow {
private int clientNumber;
private String recordNumber;
private String takeoverMonth;
private int takeovers;
private int mainClaims;
private int distinctContractDates;
private LocalDate contractDate;
public DbRow(int clientNumber, String recordNumber, String takeoverMonth, int takeovers,
int mainClaims, int distinctContractDates, LocalDate contractDate) {
super();
this.clientNumber = clientNumber;
this.recordNumber = recordNumber;
this.takeoverMonth = takeoverMonth;
this.takeovers = takeovers;
this.mainClaims = mainClaims;
this.distinctContractDates = distinctContractDates;
this.contractDate = contractDate;
}
// getters & setters
// hashCode, equals & toString
}
我目前将接收到的对象存储在Map<Integer, List<DbRow>>
中,以使它们由某个属性分开(在本例中为clientNumber
,所有DbRow
具有特定的客户编号)存储在List<DbRow>>
中,而其密钥是此特定客户号。
我需要在其中创建一个Map<Integer, Map<String, Map<LocalDate, Integer>>>
,我目前使用很多代码行。
所需结果可描述为
每个客户月每个接管月的不同合同日期计数
(例如Map<
客户编号, Map<
收购月份, Map<
合同日期,
数量>>>
)
接管月份为String
格式的"yyyy/MM"
。
我当前的解决方案很丑陋,但是可行。它包含子图的创建和填充,以及检查我想摆脱的现有键。请看看:
Map<Integer, List<DbRow>> records = new TreeMap<>();
// fill records with database results ...
Map<Integer, Map<String, Map<LocalDate, Integer>>> results = new TreeMap<>();
records.forEach((clientNumber, dbRows) -> {
Map<String, List<DbRow>> rowsPerMonth = dbRows.stream()
.collect(Collectors.groupingBy(DbRow::getTakeoverMonth));
Map<String, Map<LocalDate, Integer>> monthResults = new TreeMap<>();
rowsPerMonth.forEach((takeoverMonth, rows) -> {
if (monthResults.containsKey(takeoverMonth)) {
Map<LocalDate, Integer> contractDateCount = monthResults.get(takeoverMonth);
rows.forEach(dbRow -> {
LocalDate contractDate = dbRow.getContractDate();
if (contractDateCount.containsKey(contractDate)) {
int count = contractDateCount.get(contractDate);
count++;
contractDateCount.put(contractDate, count);
} else {
contractDateCount.put(contractDate, 1);
}
});
monthResults.put(takeoverMonth, contractDateCount);
} else {
Map<LocalDate, Integer> contractDateCount = new TreeMap<>();
rows.forEach(dbRow -> {
LocalDate contractDate = dbRow.getContractDate();
if (contractDateCount.containsKey(contractDate)) {
int count = contractDateCount.get(contractDate);
count++;
contractDateCount.put(contractDate, count);
} else {
contractDateCount.put(contractDate, 1);
}
});
monthResults.put(takeoverMonth, contractDateCount);
}
});
results.put(clientNumber, monthResults);
});
有人知道(如果有)使用流API以更短的方式做到这一点的方法吗?我真的很想为此提供解决方案。
答案 0 :(得分:2)
您可能会寻找类似的东西:
Map<Integer, Map<String, Map<LocalDate, Long>>> countDistinctDatesPerMonthPerClient(List<DbRow> input) {
return input.stream()
.collect(Collectors.groupingBy(DbRow::getClientNumber,
Collectors.groupingBy(DbRow::getTakeoverMonth,
Collectors.groupingBy(DbRow::getContractDate, Collectors.counting()))));
}