19

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

4

13 回答 13

28

没有绕过空值检查,但通过一些重构,你可以让它变得轻松。

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

/**
 * 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));
}
于 2013-04-04T20:31:36.763 回答
15

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

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

不是 null 安全的,但要短得多:

public static Date min(Date... dates) {
    return Collections.min(Arrays.asList(dates));
}

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

Collections.min(Arrays.asList(date1, date2));
于 2019-12-19T19:16:53.247 回答
7

好吧,“效率”有一些不同的含义,但我认为比较三个日期不会有效率问题。事实上,它真的很便宜。您可以尝试这种方法:

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();
于 2013-04-04T20:29:32.560 回答
5

一些使用流的 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()
于 2018-05-01T13:35:37.290 回答
4

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

Date earliest = ObjectUtils.min(a, b, c);
于 2020-11-02T22:07:40.283 回答
3

同时,您可能正在使用 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);
}
于 2020-12-27T20:27:16.453 回答
2

使用 java Date 对象http://docs.oracle.com/javase/6/docs/api/java/util/Date.html

然后您可以使用这些对象的 before() 和 after() 函数

于 2013-04-04T20:21:30.047 回答
2

使用之前和之后:

  /**
     * 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;
    }
于 2017-06-05T11:18:01.377 回答
2

使用流:

Date min = Stream.of(date1, date2, etc)
  .filter(Objects::nonNull)
  .min(Date::compareTo)
  .orElse(null);

如果您的数组不包含 NULL 值,您可以使用Ordering

Ordering.natural().min(date1, date2, etc);
于 2020-04-28T06:38:16.127 回答
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);
}
于 2017-06-26T07:58:45.747 回答
0

您可以使用

date1.compareTo(anotherDate)

回报:

如果参数 Date 等于此 Date,则值为 0;如果此 Date 在 Date 参数之前,则值小于 0;如果此 Date 在 Date 参数之后,则值大于 0。

抛出:

NullPointerException - 

如果另一个日期为空。

于 2013-04-04T20:29:50.493 回答
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)))
于 2013-04-04T20:53:20.403 回答
-1
List.of(date1, date2)
                .stream()
                .min(Date::compareTo)
                .get();
于 2022-01-20T08:03:38.733 回答