缺失数据的修复

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

 

猜你喜欢

转载自kanpiaoxue.iteye.com/blog/1978291