我在Java中有三个日期:a,b,c。任何或所有这些日期可能为空。在没有大量if-else块的情况下,确定a,b,c中最早的日期的最有效方法是什么?
答案 0 :(得分:22)
没有绕过空检查,但通过一些重构,你可以轻松搞定。
创建一个安全地比较两个日期的方法:
/**
* Safely compare two dates, null being considered "greater" than a Date
* @return the earliest of the two
*/
public static Date least(Date a, Date b) {
return a == null ? b : (b == null ? a : (a.before(b) ? a : b));
}
然后将调用组合到:
Date earliest = least(least(a, b), c);
实际上,您可以将此作为任何Comparable
的通用方法:
public static <T extends Comparable<T>> T least(T a, T b) {
return a == null ? b : (b == null ? a : (a.compareTo(b) < 0 ? a : b));
}
答案 1 :(得分:6)
嗯,'高效'有一些不同的含义,但我不认为比较三个日期会有效率问题。事实上,它真的很便宜。您可以尝试这种方法:
SortedSet<Date> dates = new TreeSet<Date>();
dates.add(date1);
dates.add(date2);
// ...
dates.add(dateN);
Date earliest = dates.first();
或者,也许更优雅:
for (Date date : someDates) {
if (date != null) {
dates.add(date);
}
}
Date earliest = dates.first();
答案 2 :(得分:2)
使用java Date对象http://docs.oracle.com/javase/6/docs/api/java/util/Date.html
您可以使用这些对象的before()和after()函数
答案 3 :(得分:2)
一些使用流的Java 8方法。第一个将在比较之前过滤空值,第二个将它们放在列表的末尾。
Date minDate = Arrays.asList(date1, date2, etc).stream()
.filter(Objects::nonNull).min(Date::compareTo).get()
或
Date minDate = Arrays.asList(date1, date2, etc).stream()
.sorted((a, b) -> {
//some kind of custom sort.
if(a == null && b == null) return 0;
if(a == null) return 1;
if(b == null) return -1;
return a.compareTo(b);
}).findFirst().get()
答案 4 :(得分:2)
使用流:
Date min = Stream.of(date1, date2, etc)
.filter(Objects::nonNull)
.min(Date::compareTo)
.orElse(null);
如果您的数组不包含NULL值,则可以使用Ordering
Ordering.natural().min(date1, date2, etc);
答案 5 :(得分:2)
与此同时,您可能正在使用 Java 8 LocalDate(而不是旧的 java.util.Date)
对于 Java 8 LocalDate 使用此方法获取最早的日期列表:
import java.time.LocalDate;
public static LocalDate earliestDate(LocalDate... dates) {
return
Arrays
.stream(dates)
.filter(Objects::nonNull)
.min(LocalDate::compareTo)
.orElse(null);
}
答案 6 :(得分:1)
使用之前和之后:
/**
* find Min Dates
* @param date1
* @param date2
* @return
*/
public static Date minDate(Date date1, Date date2) {
// if date1 before date2 then return date1 else return date2
return date1.before(date2) ? date1 : date2;
}
/**
* find Max Dates
* @param date1
* @param date2
* @return
*/
public static Date maxDate(Date date1, Date date2) {
// if date1 after date2 then return date1 else return date2
return date1.after(date2) ? date1 : date2;
}
答案 7 :(得分:1)
另一种方法是使用java.util.Collections.min(collection):
返回: 根据元素的自然顺序,给定集合的最小元素。
public static Date getEarliestDate(List<Date> dates) {
if (dates == null || dates.isEmpty())
return null;
dates.removeIf(Objects::isNull);
return dates.isEmpty() ? null : Collections.min(dates);
}
答案 8 :(得分:0)
您可以使用
date1.compareTo(anotherDate)
返回:
如果参数Date等于此Date,则值为0;如果此Date在Date参数之前,则小于0的值;如果此Date在Date参数之后,则值大于0.
抛出:
NullPointerException -
如果anotherDate为null。
答案 9 :(得分:0)
只是另一个版本作为一个想法和乐趣
new Date(Math.min(a != null ? a.getTime() : Long.MAX_VALUE
, Math.min(b != null ? b.getTime() : Long.MAX_VALUE
, c != null ? c.getTime() : Long.MAX_VALUE)))
答案 10 :(得分:0)
Java 8+ oneliner。为了安全起见,添加了空检查。传递任意数量的日期。
public static Date min(Date... dates) {
return Arrays.stream(dates).filter(Objects::nonNull).min(Date::compareTo).orElse(null);
}
不是不安全的,但更短:
public static Date min(Date... dates) {
return Collections.min(Arrays.asList(dates));
}
不是没有空值的安全性,而没有新的方法:
Collections.min(Arrays.asList(date1, date2));
答案 11 :(得分:0)
当Apache Commons可用时,您可以使用ObjectUtils.min
:
Date earliest = ObjectUtils.min(a, b, c);