我们在做页面的数据表的时候,经常会遇到这样的问题:要显示一个起始日期到一个结束日期的时间段的所有的数据。但是,往往因为各种各样的原因,造成数据缺失。比如:远程的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;
}