我有一个日期列表和一个目标日期对象。我需要找到最近的上一个日期(在目标日期之前)。我已经尝试了以下方法,但我认为它仅适用于以前的日期。
private Date getDateNearest(List<Date> dates, Date targetDate) {
Date returnDate = targetDate;
for (Date date : dates) {
if (date.compareTo(targetDate) <= 0 && date.compareTo(returnDate) > 0) {
returnDate=date;
}
}
return returnDate;
}
标准库单行
由于Date
实现了Comparable
,这应该像
Date previousDate = new TreeSet<Date>(dates).lower(targetDate);
显然,为了方便单行,这会带来一些额外的开销。
来自 Javadoc for lower()
:
返回此集合中严格小于给定元素的最大元素,如果没有此类元素,则返回 null。
编辑:查看您的代码,如果它在集合中,您似乎还想返回targetDate
本身,因此您可以使用floor(targetDate)
。
番石榴方法
以下是使用番石榴的高性能单行本:
Date earlierDate = Ordering.natural().max(
Iterables.filter(dates, Range.lessThan(targetDate)));
与纯 Java 方法不同,这不需要填充额外的数据结构,只需要一次列表传递。 它创建一个延迟填充的Iterable
,仅包含小于 targetDate
的日期,然后获取该可迭代对象的最大值。
同样,如果您希望它也接受targetDate
,请使用 Range.atMost
而不是 Range.lessThan
.
这应该会有所帮助
private Date getDateNearest(List<Date> dates, Date targetDate) {
Date returnDate = targetDate;
long targetMillis = targetDate.getTime();
long mindiff = Long.MAX_VALUE;
for (Date date : dates) {
long dateMillis = date.getTime();
long diff = Math.abs(dateMillis-targetMillis);
if( diff < mindiff){
mindiff = diff;
returnDate = date;
}
}
return returnDate;
}
private Date getDateNearest(List<Date> dates, Date targetDate) {
Date returnDate = null; // Nearest before.
for (Date date : dates) {
if (date.before(targetDate) || date.equals(targetDate) {
if (returnDate == null || returnDate.before(date)) {
returnDate = date;
}
}
}
return returnDate;
}
您的错误:在目标日期上初始化返回日期给出了无与伦比的最接近最优值。注意,也许:
return returnDate == null ? targetDate : returnDate;
顺便说一句,4月1日?(编辑问题。大声笑