查找3个日期中最早的日期

Ace*_*Ace 13 java date

我在Java中有三个日期:a,b,c.任何或所有这些日期可能为空.在没有大量if-else块的情况下,确定a,b,c中最早日期的最有效方法是什么?

Boh*_*ian 23

没有绕过空检查,但通过一些重构,你可以使它无痛.

创建一个安全地比较两个日期的方法:

/**
 * 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));
}
Run Code Online (Sandbox Code Playgroud)

然后将调用组合到:

Date earliest = least(least(a, b), c);
Run Code Online (Sandbox Code Playgroud)

实际上,您可以将其作为任何通用方法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));
}
Run Code Online (Sandbox Code Playgroud)


pav*_*ety 11

Java 8+ 单线。为了安全起见,添加了空检查。传递任意数量的日期。

public static Date min(Date... dates) {
    return Arrays.stream(dates).filter(Objects::nonNull).min(Date::compareTo).orElse(null);
}
Run Code Online (Sandbox Code Playgroud)

不是 null safe,但要短得多:

public static Date min(Date... dates) {
    return Collections.min(Arrays.asList(dates));
}
Run Code Online (Sandbox Code Playgroud)

没有新方法就不是空安全的

Collections.min(Arrays.asList(date1, date2));
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用 Java 或更高版本,则不应使用“Date”。该类设计不佳且早已过时。根据具体要求,使用“Instant”或 [java.time,现代 Java 日期和时间 API](https://docs.oracle.com/javase/tutorial/datetime/) 中的另一个类。即使在 Java 6 或 7 上,您也可以考虑使用 [ThreeTen Backport](https://www.thirden.org/thirdenbp/)。 (2认同)

n0n*_*ick 10

当 Apache Commons 可用时,您可以使用ObjectUtils.min

Date earliest = ObjectUtils.min(a, b, c);
Run Code Online (Sandbox Code Playgroud)


Grz*_*ski 6

那么,'高效'有一些不同的含义,但我不认为比较三个日期会有效率问题.事实上,它真的很便宜.你可以尝试这种方法:

SortedSet<Date> dates = new TreeSet<Date>();
dates.add(date1);
dates.add(date2);
// ...
dates.add(dateN);
Date earliest = dates.first();
Run Code Online (Sandbox Code Playgroud)

或者,也许更优雅:

for (Date date : someDates) {
   if (date != null) {
      dates.add(date);
   }
}
Date earliest = dates.first();
Run Code Online (Sandbox Code Playgroud)


ygl*_*odt 6

同时,您可能正在使用 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);
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*nny 5

一些使用流的 Java 8 方法。第一个将在比较之前过滤空值,第二个将它们放在列表的末尾。

Date minDate = Arrays.asList(date1, date2, etc).stream()
     .filter(Objects::nonNull).min(Date::compareTo).get()
Run Code Online (Sandbox Code Playgroud)

或者

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()
Run Code Online (Sandbox Code Playgroud)