【发布时间】:2010-09-25 17:57:33
【问题描述】:
我有一个按日期排序的数据表,用户可以通过提供开始和结束日期从中选择一组数据。数据本身是不连续的,因为我没有周末和公共假期的数据。
我希望能够在提取的数据集中列出我没有数据的所有日子。有没有一种简单的方法,在 Java 中,去:
- 这是一个有序的日期数组。
- 这是选定的开始日期。 (数组中的第一个日期并不总是开始日期)
- 这是选定的结束日期。 (数组中的最后一个日期并不总是结束日期)
- 返回没有数据的日期列表。
【问题讨论】:
我有一个按日期排序的数据表,用户可以通过提供开始和结束日期从中选择一组数据。数据本身是不连续的,因为我没有周末和公共假期的数据。
我希望能够在提取的数据集中列出我没有数据的所有日子。有没有一种简单的方法,在 Java 中,去:
【问题讨论】:
您可以创建一个临时列表并根据需要对其进行 x。
(不是真正的 Java。抱歉,我对它的记忆很糟糕。)
dates = [...]; // list you have now;
// build list
unused = [];
for (Date i = startdate; i < enddate; i += day) {
unused.push(i);
}
// remove used dates
for (int j = 0; j < dates.length; j += 1) {
if (unused.indexOf((Date) dates[j]) > -1) { // time = 00:00:00
unused.remove(unused.indexOf((Date) dates[j]));
}
}
【讨论】:
您应该能够创建提供此功能的过滤迭代器。也许让迭代器的方法接受子集合的开始和停止日期。至于迭代器的实际实现,我想不出比在找到起始元素后对整个集合进行蛮力运行更优雅的方法了。
【讨论】:
您可以创建一个包含开始日期和结束日期之间所有可能日期的列表,然后删除出现在给定数据列表中的日期(当大多数日期缺失时效果最好),或者您可以从一个空的日期列表开始并添加未出现在给定数据中的那些。
无论哪种方式,您基本上都会遍历开始日期和结束日期之间的日期范围,跟踪您在给定日期列表中的位置。您可以将其视为“类似合并”的操作,您可以并行遍历两个列表,处理出现在一个列表中但不在另一个列表中的记录。在伪代码中,空列表版本可能是:
# given - array of given dates
# N - number of dates in given array
# missing - array of dates missing
i = 0; # Index into given date array
j = 0; # Index into missing data array
for (current_date = start_date; current_date <= end_date; current_date++)
{
while (given[i] < current_date && i < N)
i++
if (i >= N)
break
if (given[i] != current_date)
missing[j++] = current_date
}
while (current_date < end_date)
{
missing[j++] = current_date
current_date++
}
我假设日期类型是以一天为单位量化的;也就是说,date + 1(或date++)是date之后的第二天。
【讨论】:
虽然已经给出的其他答案看起来相当简单和令人愉快并且有一些好主意(我特别同意 Nerdfest 的迭代器建议),但我想我还是会试一试并编写一个解决方案来展示我如何'会在第一次迭代中完成,我相信下面的内容还有改进的余地。
我也可能对您的要求过于字面理解,但您知道如何根据自己的喜好调整代码。哦,对可怕的对象命名感到抱歉。此外,由于此示例使用 Calendar,请记住 Calendar.roll() 在某些情况下可能不会更新整个 Calendar 对象,因此这是一个潜在的错误。
protected List<Calendar> getDatesWithNoData(Calendar start, Calendar end,
Calendar[] existingDates) throws ParseException {
List<Calendar> missingData = new ArrayList<Calendar>();
for(Calendar c=start ; c.compareTo(end)<=0 ; c.roll(Calendar.DAY_OF_MONTH, true) ) {
if(!isInDataSet(c, existingDates)) {
Calendar c2 = Calendar.getInstance();
c2.setTimeInMillis(c.getTimeInMillis());
missingData.add(c2);
}
}
return missingData;
}
protected boolean isInDataSet(Calendar toSearch, Calendar[] dataSet) {
for(Calendar l : dataSet) {
if(toSearch.equals(l)) return true;
}
return false;
}
【讨论】: