У меня три даты в Java: a, b, c. Любая или все эти даты могут быть пустыми. Каков наиболее эффективный способ определения самой ранней даты среди a, b, c без массивного блока if-else?
Найдите самую раннюю дату среди 3 дат
Ответ 1
Там нет обхода нулевой проверки, но с некоторым рефакторингом вы можете сделать это безболезненным.
Создайте метод, который безопасно сравнивает две даты:
/**
* 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));
}
Ответ 2
Ну, "эффективный" имеет несколько разных значений, но я не думаю, что будет проблема эффективности при сравнении трех дат. На самом деле, это действительно дешево. Вы можете попробовать такой подход:
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();
Ответ 3
Использовать объект даты java http://docs.oracle.com/javase/6/docs/api/java/util/Date.html
Вы можете использовать функции before() и after() этих объектов, затем
Ответ 4
используя до и после:
/**
* 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;
}
Ответ 5
Другой способ - использовать java.util.Collections.min(коллекция):
Возвращает: минимальный элемент данного набора, в соответствии с естественным упорядочением его элементов.
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);
}
Ответ 6
Вы можете использовать
date1.compareTo(anotherDate)
Возврат:
значение 0, если аргумент Date равен этой дате; значение меньше 0, если эта дата предшествует аргументу Date; и значение больше 0, если эта дата после аргумента Date.
Броски:
NullPointerException -
если anotherDate имеет значение null.
Ответ 7
просто другая версия как идея и для удовольствия
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)))
Ответ 8
Некоторые методы 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()