转换地图<;整数,列表<;对象>&燃气轮机;映射<;整数,Map<;字符串,Map<;LocalDate,整数>&燃气轮机&燃气轮机;使用Java流API
我从数据库接收一些结果集,并将每一行存储为转换地图<;整数,列表<;对象>&燃气轮机;映射<;整数,Map<;字符串,Map<;LocalDate,整数>&燃气轮机&燃气轮机;使用Java流API,java,java-stream,Java,Java Stream,我从数据库接收一些结果集,并将每一行存储为DbRow类型的对象,这是一个类: public class DbRow { private int clientNumber; private String recordNumber; private String takeoverMonth; private int takeovers; private int mainClaims; private int distinctContractDates
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
}
我当前将接收到的对象存储在映射中
,以便通过特定属性将它们分开(在本例中,clientNumber
,所有具有特定客户端编号的DbRow
存储在列表>
中,而它们的键是该特定客户端编号)
我需要用它创建一个Map
,我目前使用了很多行代码
期望的结果可以描述为每个客户编号每个接管月的不同合同日期计数
(如
Map
)其中接管月份是格式为
“yyyy/MM”
的字符串 我目前的解决方案很难看,但有效。它包含子映射的创建和填充,以及检查我想要删除的现有密钥。请看一下:
作为某种契约提取。object@TobiasRoland是的,我也想到了这个想法…@Naman几周后再读一遍也要花很多时间,这就是为什么我在寻找更好的解决方案……这就是我一直在寻找的,除了数字类型(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); });
Map records=newtreemap(); //用数据库结果填充记录。。。 映射结果=新树映射(); records.forEach((clientNumber,dbRows)->{ Map rowserMonth=dbRows.stream() .collect(Collectors.groupingBy(DbRow::getTakeoverMonth)); Map monthResults=new TreeMap(); rowsPerMonth.forEach((接管月,行)->{ if(每月结果containsKey(接管月)){ Map contractDateCount=monthResults.get(takeoverMonth); rows.forEach(dbRow->{ LocalDate contractDate=dbRow.getContractDate(); if(合同日期计数。集装箱(合同日期)){ int count=contractDateCount.get(contractDate); 计数++; contractDateCount.put(contractDate,count); }否则{ contractDateCount.put(contractDate,1); } }); monthResults.put(接管月、合同日期计数); }否则{ Map contractDateCount=新树映射(); rows.forEach(dbRow->{ LocalDate contractDate=dbRow.getContractDate(); if(合同日期计数。集装箱(合同日期)){ int count=contractDateCount.get(contractDate); 计数++; contractDateCount.put(contractDate,count); }否则{ contractDateCount.put(contractDate,1); } }); monthResults.put(接管月、合同日期计数); } }); 结果。put(客户编号、月结果); });
有人知道(如果有)一种使用流API以较短的方式完成此任务的方法吗?我真的很想为它找到一个漂亮的解决方案。您可能正在寻找类似以下内容的解决方案: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())))); }
看起来像一个嵌套的Map countdistinctdatespermonperClient(列表输入){ 返回input.stream() .collect(收集器.groupingBy(DbRow::getClientNumber、, Collectors.groupby(DbRow::getTakeoverMonth, Collectors.groupby(DbRow::getContractDate,Collectors.counting()); }
,带有groupby
用例。但老实说,要读取代码堆栈将需要一些空闲。考虑到嵌套的地图泛型,我会考虑将您的代码> map计数
,而不是Long
),但这并不重要。谢谢Integer