我们在做页面的数据表的时候,经常会遇到这样的问题:要显示一个起始日期到一个结束日期的时间段的所有的数据。但是,往往因为各种各样的原因,造成数据缺失。比如:远程的log服务器损坏,网络突然中断造成数据丢失,等等。
我们一般会这样处理:对缺失的数据,进行补 0 操作。
方法论:全集与子集的关系。
我们可以找到一个全集 A,那么我们要修补的数据,就应该是该全集A的一个子集B。该子集B的元素数量<=全集A的元素数量。我们需要对全集A进行循环,并判断该子集B中是否存在该元素,当不存在的时候,进行数据修复,补0操作。
起始日期:2011-01-01,结束日期:2011-02-28。中间缺失数据的日期:2011-01-17,2011-02-01等等。
这样,我们就有一个全集:2011-01-01到2011-02-28的时间列表,便是全集。那么2011-01-01到2011-02-28的时间段并缺失了数据的列表,便是子集。
public static void testRepairCollection() { String startDate = "2011-01-01"; String endDate = "2011-02-28"; Collection<String> dates = getDateList(startDate, endDate); // 得到的数据Map是数据缺失的不完整的Map Map<String, Integer> badDatas = createBadDatas(dates); // 打印出修复之后的数据的结果 for (Map.Entry<String, Integer> entry : badDatas.entrySet()) { System.out.println(entry.getKey() + " --> " + entry.getValue()); } System.out.println("======================================size:" + badDatas.size()); Map<String, Integer> correctDataMap = new LinkedHashMap<String, Integer>(); // 这里根据全集的dates,进行数据修复 for (String date : dates) { correctDataMap.put(date, badDatas.containsKey(date) ? badDatas.get(date) : 0); } System.out.println("======================================size:" + correctDataMap.size()); // 打印出修复之后的数据的结果 for (Map.Entry<String, Integer> entry : correctDataMap.entrySet()) { System.out.println(entry.getKey() + " --> " + entry.getValue()); } } private static Map<String, Integer> createBadDatas(Collection<String> dates) { Map<String, Integer> map = new LinkedHashMap<String, Integer>(); int i = 0; Random random = new Random(); for (String date : dates) { if ((i++) % 7 != 0) { map.put(date, i + random.nextInt(100)); } } return map; } /** * @param startDate * pattern:yyyy-MM-dd * @param endDate * pattern:yyyy-MM-dd * @return 两个日期之间的日期列表,包含“起始日期和结束日期” */ public static Collection<String> getDateList(String startDate, String endDate) { String pattern = "yyyy-MM-dd"; return getDateList(startDate, endDate, pattern); } /** * @param startDate * 起始日期 * @param endDate * 结束日期 * @param pattern * 格式化日期的表达式:如 yyyy-MM-dd * @return 两个日期之间的日期列表,包含“起始日期和结束日期” */ public static Collection<String> getDateList(String startDate, String endDate, String pattern) { SimpleDateFormat format = new SimpleDateFormat(pattern); Collection<String> list = new ArrayList<String>(); try { Date start = format.parse(startDate); Date end = format.parse(endDate); if (start.after(end)) { throw new IllegalArgumentException( "Error:startDate is after endDate!"); } Calendar c1 = Calendar.getInstance(); c1.setTime(start); while (c1.getTime().getTime() <= end.getTime()) { list.add(format.format(c1.getTime())); c1.add(Calendar.DAY_OF_YEAR, 1); } } catch (ParseException e) { e.printStackTrace(); } return list; }