ТЛ; др
То, что я хочу сделать, это отсортировать все начало DateTime и все конец DateTime по дате.
Вы можете сделать одно или другое, но не оба.
Для сортировки по дате начала (на практике это представляется целесообразным), используйте метод compareTo
.
return this.getDateRange().getStart().compareTo( thatStart );
Для сортировки по дате окончания (я не вижу в этом никакого смысла), реализуем интерфейс Comparator
.
return
t1.getDateRange().getEnd().compareTo(
t2.getDateRange().getEnd()
)
;
LocalDate
Как уже отмечалось, вы должны использовать современные java.time классы, а не ужасные старые Date
/ Calendar
/ SimpleDateFormat
. Для значения только для даты, без времени суток и без часового пояса, используйте LocalDate
.
LocalDateRange
Как указано в Answer by jbx , вы должны представлять даты начала и окончания вашего термина в паре. Но не пишите класс, если он уже существует. Используйте класс LocalDateRange
из проекта ThreeTen-Extra . Этот проект добавляет функциональность классам java.time .
Comparable
В вашем классе Term
реализуйте интерфейс Comparable
для простой и удобной сортировки. Добавьте метод compareTo
. Очевидный подход заключается в сравнении начальных LocalDate
каждого Term
объекта LocalDateRange
объекта.
Класс LocalDate
реализует compareTo
, нет, нам не нужно.
@Override
public int compareTo ( Object o ) {
if ( this == o ) return 0;
if ( o == null || getClass() != o.getClass() ) return 0;
LocalDate thatStart = ( ( Term ) o ).getDateRange().getStart();
return this.getDateRange().getStart().compareTo( thatStart );
}
См. Java Tutorial по упорядочению объектов .
Сортировать по дате остановки
Ваш вопрос неясен, но вы, похоже, просите альтернативно отсортировать по дате окончания. Я не могу себе представить, насколько это полезно на практике. Но в любом случае, решение заключается в сортировке, предоставляя реализацию интерфейса Comparator
.
@Override
public int compare ( Term t1 , Term t2 ) {
return t1.getDateRange().getEnd().compareTo( t2.getDateRange().getEnd() );
}
Пример класса
Вот пример Term
класса. Может быть, это не код качества производства, но вы должны двигаться в правильном направлении.
package com.basilbourque.example;
import org.threeten.extra.LocalDateRange;
import java.time.LocalDate;
import java.time.Month;
import java.util.*;
public class Term implements Comparable {
private UUID id;
private LocalDateRange dateRange;
// Constructor
public Term ( LocalDate start , LocalDate stop , UUID id ) {
Objects.requireNonNull( start ); // TODO: Add more such checks for all arguments.
if ( start.getYear() < 2015 ) { // TODO: Add more such checks for too far into the past or future, for both start and for stop.
throw new IllegalArgumentException( "Year of start date is too far in the past. Message # afcd30a0-b639-4ccf-b064-18cc2ea8587b." );
}
this.id = id;
this.dateRange = LocalDateRange.of( start , stop );
}
// Alternative constructor.
public Term ( LocalDateRange dateRange , UUID id ) {
this( dateRange.getStart() , dateRange.getEnd() , id );
}
// --------| Object |-------------------------
@Override
public String toString ( ) {
return "Term{ " +
"id=" + id +
" | dateRange=" + dateRange +
" }";
}
public UUID getId ( ) {
return id;
}
public LocalDateRange getDateRange ( ) {
return dateRange;
}
@Override
public boolean equals ( Object o ) {
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
Term term = ( Term ) o;
return this.getId().equals( term.getId() );
}
@Override
public int hashCode ( ) {
return Objects.hash( this.getId() );
}
@Override
public int compareTo ( Object o ) {
if ( this == o ) return 0; // If same object.
if ( o == null || getClass() != o.getClass() ) return 0;
LocalDate thatStart = ( ( Term ) o ).getDateRange().getStart();
return this.getDateRange().getStart().compareTo( thatStart );
}
static public class StopDateComparator implements Comparator < Term > {
@Override
public int compare ( Term t1 , Term t2 ) {
return t1.getDateRange().getEnd().compareTo( t2.getDateRange().getEnd() );
}
}
}
Попробуй.
public static void main ( String[] args ) {
Term t1 = new Term( LocalDate.of( 2018 , Month.JUNE , 23 ) , LocalDate.of( 2018 , Month.JULY , 23 ) , UUID.randomUUID() );
Term t2 = new Term( LocalDate.of( 2018 , Month.JANUARY , 23 ) , LocalDate.of( 2018 , Month.DECEMBER , 23 ) , UUID.randomUUID() );
Term t3 = new Term( LocalDate.of( 2018 , Month.MARCH , 23 ) , LocalDate.of( 2018 , Month.APRIL , 23 ) , UUID.randomUUID() );
List < Term > terms = new ArrayList <>( List.of( t1 , t2 , t3 ) );
System.out.println( "Before natural sort: " + terms );
Collections.sort( terms );
System.out.println( "After natural sort: " + terms );
Collections.sort( terms , new Term.StopDateComparator() );
System.out.println( "After Comparator sort: " + terms );
}
Перед естественной сортировкой: [Term {id = 27c0b9e6-076f-4ded-9bbd-bf1a2c7914bc | dateRange = 2018-06-23 / 2018-07-23}, термин {id = 792bf365-eca4-460b-afad-c5cf62cf9a29 | dateRange = 2018-01-23 / 2018-12-23}, термин {id = c49f79e1-11cd-4865-aa46-8fbf3c85dbfd | dateRange = 2018-03-23 / 2018-04-23}]
После естественной сортировки: [Term {id = 792bf365-eca4-460b-afad-c5cf62cf9a29 | dateRange = 2018-01-23 / 2018-12-23}, термин {id = c49f79e1-11cd-4865-aa46-8fbf3c85dbfd | dateRange = 2018-03-23 / 2018-04-23}, термин {id = 27c0b9e6-076f-4ded-9bbd-bf1a2c7914bc | dateRange = 2018-06-23 / 2018-07-23}]
После сортировки компаратора: [Term {id = c49f79e1-11cd-4865-aa46-8fbf3c85dbfd | dateRange = 2018-03-23 / 2018-04-23}, термин {id = 27c0b9e6-076f-4ded-9bbd-bf1a2c7914bc | dateRange = 2018-06-23 / 2018-07-23}, термин {id = 792bf365-eca4-460b-afad-c5cf62cf9a29 | dateRange = 2018-01-23 / 2018-12-23}]
abuts
Если ваши Term
объекты должны сталкиваться друг с другом последовательно, вы можете проверить это, используя метод LocalDateRange::abuts
.
Подход в сравнении - Half-Open, где начало включительно , а окончание эксклюзив . Таким образом, год начинается с первого года и продолжается, но не включает в себя, первый из следующего года. Вы показываете это в своих примерах в вопросе.