如何比较实例化的 DateTime 对象?

我正在编写一个程序来按日期对日期时间进行排序。有一个 DateTime 开始和一个 DateTime 结束。这些从用户输入中放入它们自己的对象中。DateTime 开始和 DateTime 结束组成了它们自己的术语。因此,每个术语都有自己的对象,以 DateTime 开头和 DateTime 结尾。


我想要做的是按日期对所有 DateTime 开始和所有 DateTime 结束进行排序。我怎样才能做到这一点?我正在考虑一个比较器,但我似乎无法在自定义对象上执行此操作。


因此,假设用户输入 onebeginning date of 01/01/2000和 one end date of 01/01/2002。这构成了一个术语。然后,用户输入由 abeginning date of 01/01/2001和 an组成的第二项end date of 01/01/2003。


我现在要做的是对日期进行排序并创建三个新术语,即:


beginning 01/01/2000 end 01/01/2001


beginning 01/01/2001 end 01/01/2002


beginning 01/01/2002 end 01/01/2003

我被困在如何继续这个问题上,有什么想法吗?


呼如林
浏览 203回答 3
3回答

大话西游666

将每个日期放入一个新集合中,按日期对其进行排序,然后创建包含集合中相邻日期的新对象。尝试:public static void main(String[] args) {&nbsp; &nbsp; List<YourClass> list = new ArrayList<>();&nbsp; &nbsp; list.add(new YourClass(new Date(100000000), new Date(200000000)));&nbsp; &nbsp; list.add(new YourClass(new Date(150000000), new Date(250000000)));&nbsp; &nbsp; list.add(new YourClass(new Date(50000000), new Date(300000000)));&nbsp; &nbsp; System.out.println(list);&nbsp; &nbsp; List<Date> dates = new ArrayList<>();&nbsp; &nbsp; for (YourClass yc : list){&nbsp; &nbsp; &nbsp; &nbsp; if (!dates.contains(yc.beginning)) dates.add(yc.beginning);&nbsp; &nbsp; &nbsp; &nbsp; if (!dates.contains(yc.end)) dates.add(yc.end);&nbsp; &nbsp; }&nbsp; &nbsp; Collections.sort(dates);&nbsp; &nbsp; List<YourClass> list2 = new ArrayList<>();&nbsp; &nbsp; for (int i=0; i < dates.size() -1; i++){&nbsp; &nbsp; &nbsp; &nbsp; list2.add(new YourClass(dates.get(i), dates.get(i+1)));&nbsp; &nbsp; }&nbsp; &nbsp; System.out.println(list2);}public static class YourClass {&nbsp; &nbsp; Date beginning;&nbsp; &nbsp; Date end;&nbsp; &nbsp; public YourClass(Date beginning, Date end) {&nbsp; &nbsp; &nbsp; &nbsp; this.beginning = beginning;&nbsp; &nbsp; &nbsp; &nbsp; this.end = end;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public String toString() {&nbsp; &nbsp; &nbsp; &nbsp; return "\n" + beginning&nbsp; + " -> " + end ;&nbsp; &nbsp; }}

小怪兽爱吃肉

我想要做的是按日期对所有 DateTime 开始和所有 DateTime 结束进行排序。你可以做一个或另一个,但不能同时做。要按开始日期排序(在实践中似乎很明智),请实现compareTo方法。return this.getDateRange().getStart().compareTo( thatStart );要按停止日期排序(我认为这没有任何意义),请实现Comparator接口。return&nbsp;&nbsp; &nbsp; t1.getDateRange().getEnd().compareTo(&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; t2.getDateRange().getEnd()&nbsp;&nbsp; &nbsp; );LocalDate正如其他人所指出的,您应该使用现代java.time类,而不是可怕的旧Date//类Calendar。SimpleDateFormat对于仅日期值,没有时间和时区,请使用LocalDate.LocalDateRange正如jbx 的答案所讨论的,您应该将您的学期的开始日期和结束日期表示为一对。但是当一个类已经存在时不要写一个类。使用ThreeTen-Extra项目中LocalDateRange的类。该项目为java.time类添加了功能。Comparable在您的Term类上,实现Comparable接口以启用简单轻松的排序。添加方法compareTo。显而易见的方法是比较LocalDate每个Term对象的LocalDateRange对象的开始。该类LocalDate实现compareTo了,不,我们不必这样做。@Overridepublic int compareTo ( Object o ) {&nbsp; &nbsp; if ( this == o ) return 0;&nbsp; &nbsp; if ( o == null || getClass() != o.getClass() ) return 0;&nbsp; &nbsp; LocalDate thatStart = ( ( Term ) o ).getDateRange().getStart();&nbsp; &nbsp; return this.getDateRange().getStart().compareTo( thatStart );}请参阅有关对象排序的 Java 教程。按停止日期排序您的问题不清楚,但您似乎要求按结束日期进行排序。我无法想象这在实际中是如何有用的。但无论如何,解决方案是通过提供Comparator接口的实现来进行排序。&nbsp; &nbsp; @Override&nbsp; &nbsp; public int compare ( Term t1 , Term t2 ) {&nbsp; &nbsp; &nbsp; &nbsp; return t1.getDateRange().getEnd().compareTo( t2.getDateRange().getEnd() );&nbsp; &nbsp; }示例类这是一个示例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 {&nbsp; &nbsp; private UUID id;&nbsp; &nbsp; private LocalDateRange dateRange;&nbsp; &nbsp; // Constructor&nbsp; &nbsp; public Term ( LocalDate start , LocalDate stop , UUID id ) {&nbsp; &nbsp; &nbsp; &nbsp; Objects.requireNonNull( start ); // TODO: Add more such checks for all arguments.&nbsp; &nbsp; &nbsp; &nbsp; if ( start.getYear() < 2015 ) {&nbsp; // TODO: Add more such checks for too far into the past or future, for both start and for stop.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException( "Year of start date is too far in the past. Message # afcd30a0-b639-4ccf-b064-18cc2ea8587b." );&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; this.id = id;&nbsp; &nbsp; &nbsp; &nbsp; this.dateRange = LocalDateRange.of( start , stop );&nbsp; &nbsp; }&nbsp; &nbsp; // Alternative constructor.&nbsp; &nbsp; public Term ( LocalDateRange dateRange , UUID id ) {&nbsp; &nbsp; &nbsp; &nbsp; this( dateRange.getStart() , dateRange.getEnd() , id );&nbsp; &nbsp; }&nbsp; &nbsp; // --------|&nbsp; Object&nbsp; |-------------------------&nbsp; &nbsp; @Override&nbsp; &nbsp; public String toString ( ) {&nbsp; &nbsp; &nbsp; &nbsp; return "Term{ " +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "id=" + id +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " | dateRange=" + dateRange +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " }";&nbsp; &nbsp; }&nbsp; &nbsp; public UUID getId ( ) {&nbsp; &nbsp; &nbsp; &nbsp; return id;&nbsp; &nbsp; }&nbsp; &nbsp; public LocalDateRange getDateRange ( ) {&nbsp; &nbsp; &nbsp; &nbsp; return dateRange;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean equals ( Object o ) {&nbsp; &nbsp; &nbsp; &nbsp; if ( this == o ) return true;&nbsp; &nbsp; &nbsp; &nbsp; if ( o == null || getClass() != o.getClass() ) return false;&nbsp; &nbsp; &nbsp; &nbsp; Term term = ( Term ) o;&nbsp; &nbsp; &nbsp; &nbsp; return this.getId().equals( term.getId() );&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public int hashCode ( ) {&nbsp; &nbsp; &nbsp; &nbsp; return Objects.hash( this.getId() );&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public int compareTo ( Object o ) {&nbsp; &nbsp; &nbsp; &nbsp; if ( this == o ) return 0;&nbsp; // If same object.&nbsp; &nbsp; &nbsp; &nbsp; if ( o == null || getClass() != o.getClass() ) return 0;&nbsp; &nbsp; &nbsp; &nbsp; LocalDate thatStart = ( ( Term ) o ).getDateRange().getStart();&nbsp; &nbsp; &nbsp; &nbsp; return this.getDateRange().getStart().compareTo( thatStart );&nbsp; &nbsp; }&nbsp; &nbsp; static public class StopDateComparator implements Comparator < Term > {&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public int compare ( Term t1 , Term t2 ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return t1.getDateRange().getEnd().compareTo( t2.getDateRange().getEnd() );&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}试试看。public static void main ( String[] args ) {&nbsp; &nbsp; Term t1 = new Term( LocalDate.of( 2018 , Month.JUNE , 23 ) , LocalDate.of( 2018 , Month.JULY , 23 ) , UUID.randomUUID() );&nbsp; &nbsp; Term t2 = new Term( LocalDate.of( 2018 , Month.JANUARY , 23 ) , LocalDate.of( 2018 , Month.DECEMBER , 23 ) , UUID.randomUUID() );&nbsp; &nbsp; Term t3 = new Term( LocalDate.of( 2018 , Month.MARCH , 23 ) , LocalDate.of( 2018 , Month.APRIL , 23 ) , UUID.randomUUID() );&nbsp; &nbsp; List < Term > terms = new ArrayList <>( List.of( t1 , t2 , t3 ) );&nbsp; &nbsp; System.out.println( "Before natural sort: " + terms );&nbsp; &nbsp; Collections.sort( terms );&nbsp; &nbsp; System.out.println( "After natural sort: " + terms );&nbsp; &nbsp; Collections.sort( terms , new Term.StopDateComparator() );&nbsp; &nbsp; System.out.println( "After Comparator sort: " + terms );}自然排序前:[Term{ id=27c0b9e6-076f-4ded-9bbd-bf1a2c7914bc | 日期范围=2018-06-23/2018-07-23 },期限{ id=792bf365-eca4-460b-afad-c5cf62cf9a29 | 日期范围=2018-01-23/2018-12-23 },期限{ id=c49f79e1-11cd-4865-aa46-8fbf3c85dbfd | 日期范围=2018-03-23/2018-04-23 }]自然排序后:[Term{ id=792bf365-eca4-460b-afad-c5cf62cf9a29 | 日期范围=2018-01-23/2018-12-23 },期限{ id=c49f79e1-11cd-4865-aa46-8fbf3c85dbfd | 日期范围=2018-03-23/2018-04-23 },期限{ id=27c0b9e6-076f-4ded-9bbd-bf1a2c7914bc | 日期范围=2018-06-23/2018-07-23 }]比较器排序后:[Term{ id=c49f79e1-11cd-4865-aa46-8fbf3c85dbfd | 日期范围=2018-03-23/2018-04-23 },期限{ id=27c0b9e6-076f-4ded-9bbd-bf1a2c7914bc | 日期范围=2018-06-23/2018-07-23 },期限{ id=792bf365-eca4-460b-afad-c5cf62cf9a29 | 日期范围=2018-01-23/2018-12-23 }]abuts如果您的Term对象应该连续运行,您可以使用该LocalDateRange::abuts方法进行测试。比较的方法是半开放式,开始是包容性的,结束是排斥性的。因此,一年从一年的第一天开始,一直到但不包括下一年的第一天。您在问题的示例中展示了这一点。

慕标5832272

我认为这个问题不仅仅是关于排序,还有关于将重叠的间隔分成更小的部分。您必须经常使用Interval Arithmetic。使用 Java 8,您可以首先将“术语”编码为时间间隔,它本身就是Comparable. 如果用户指定重叠的间隔,第二部分将把你的间隔分成多个。class Interval implements Comparable<Interval> {&nbsp; private final LocalDateTime start;&nbsp; private final LocalDateTime end;&nbsp; public Interval(LocalDateTime start, LocalDateTime end) {&nbsp; &nbsp; &nbsp;this.start = start;&nbsp; &nbsp; &nbsp;this.end = end;&nbsp; }&nbsp; public int compareTo(Interval that) {&nbsp; &nbsp; return this.start.compareTo(that.start);&nbsp; }&nbsp; public boolean overlaps(Interval that) {&nbsp; &nbsp; return !this.isBefore(that) && !this.isAfter(that);&nbsp; }&nbsp; public boolean contains(Interval that) {&nbsp; &nbsp; return this.start.isBefore(that.start) && this.end.isAfter(that.end);&nbsp; }&nbsp; public boolean isBefore(Interval that) {&nbsp; &nbsp; return this.end.isBefore(that.start);&nbsp; }&nbsp; public boolean isAfter(Interval that) {&nbsp; &nbsp; return this.start.isAfter(that.end);&nbsp; }&nbsp; public Set<Interval> fragment(Interval that) {&nbsp; &nbsp; if (that.start.isBefore(this.start)) {&nbsp; &nbsp; &nbsp; return that.fragment(this);&nbsp; &nbsp; }&nbsp; &nbsp; Set<Interval> result = new HashSet<>();&nbsp; &nbsp; if (this.end.isBefore(that.start)) {&nbsp; &nbsp; &nbsp; &nbsp;result.add(this);&nbsp; &nbsp; &nbsp; &nbsp;result.add(that);&nbsp; &nbsp; &nbsp; &nbsp;result.add(new Interval(this.end, that.start));&nbsp; &nbsp; } else if ((this.end.isAfter(that.start) && this.end.isBefore(that.end)) {&nbsp; &nbsp; &nbsp; &nbsp;result.add(new Interval(this.start, that.start);&nbsp; &nbsp; &nbsp; &nbsp;result.add(new Interval(that.start, this.end);&nbsp; &nbsp; &nbsp; &nbsp;result.add(new Interval(this.end, that.end));&nbsp; &nbsp; } else if (this.end.isAfter(that.end)) {&nbsp; &nbsp; &nbsp; &nbsp;result.add(new Interval(this.start, that.start);&nbsp; &nbsp; &nbsp; &nbsp;result.add(new Interval(that);&nbsp; &nbsp; &nbsp; &nbsp;result.add(new Interval(that.end, this.end));&nbsp; &nbsp; }&nbsp; }}您现在可以对它们进行排序,因为Intervals 可以按开始日期进行比较。每当用户输入一个新的Interval(术语)时,您必须通过列表检查它是否contains()存在间隔,或者它是否在它之前,使用isBefore()或isAfter()。如果它overlaps()你必须小心是否还要检查它是否与列表中的下一个间隔重叠。然后,您可以调用fragment()which 会将 2 个间隔组合成更小的间隔。您需要小心删除以前的。因此,只需浏览列表并检查它们是否重叠可能是有意义的。如果您到达终点,您仍然可以使用fragment()组合两个不相交的间隔。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java