亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何比較實例化的 DateTime 對象?

如何比較實例化的 DateTime 對象?

呼如林 2022-01-19 12:35:37
我正在編寫一個程序來按日期對日期時間進行排序。有一個 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/2001beginning 01/01/2001 end 01/01/2002beginning 01/01/2002 end 01/01/2003我被困在如何繼續這個問題上,有什么想法嗎?
查看完整描述

3 回答

?
大話西游666

TA貢獻1817條經驗 獲得超14個贊

將每個日期放入一個新集合中,按日期對其進行排序,然后創建包含集合中相鄰日期的新對象。


嘗試:


public static void main(String[] args) {

    List<YourClass> list = new ArrayList<>();


    list.add(new YourClass(new Date(100000000), new Date(200000000)));

    list.add(new YourClass(new Date(150000000), new Date(250000000)));

    list.add(new YourClass(new Date(50000000), new Date(300000000)));


    System.out.println(list);


    List<Date> dates = new ArrayList<>();

    for (YourClass yc : list){

        if (!dates.contains(yc.beginning)) dates.add(yc.beginning);

        if (!dates.contains(yc.end)) dates.add(yc.end);

    }


    Collections.sort(dates);


    List<YourClass> list2 = new ArrayList<>();


    for (int i=0; i < dates.size() -1; i++){

        list2.add(new YourClass(dates.get(i), dates.get(i+1)));

    }


    System.out.println(list2);


}


public static class YourClass {

    Date beginning;

    Date end;


    public YourClass(Date beginning, Date end) {

        this.beginning = beginning;

        this.end = end;

    }


    @Override

    public String toString() {

        return "\n" + beginning  + " -> " + end ;

    }

}


查看完整回答
反對 回復 2022-01-19
?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

我想要做的是按日期對所有 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

正如jbx 的答案所討論的,您應該將您的學期的開始日期和結束日期表示為一對。但是當一個類已經存在時不要寫一個類。使用ThreeTen-Extra項目中LocalDateRange的類。該項目為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 教程。


按停止日期排序

您的問題不清楚,但您似乎要求按結束日期進行排序。我無法想象這在實際中是如何有用的。但無論如何,解決方案是通過提供Comparator接口的實現來進行排序。


    @Override

    public int compare ( Term t1 , Term t2 ) {

        return t1.getDateRange().getEnd().compareTo( t2.getDateRange().getEnd() );

    }

示例類

這是一個示例Term類??赡懿皇巧a質量的代碼,但應該讓你朝著正確的方向前進。


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 | 日期范圍=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方法進行測試。


比較的方法是半開放式,開始是包容性的,結束是排斥性的。因此,一年從一年的第一天開始,一直到但不包括下一年的第一天。您在問題的示例中展示了這一點。


查看完整回答
反對 回復 2022-01-19
?
慕標5832272

TA貢獻1966條經驗 獲得超4個贊

我認為這個問題不僅僅是關于排序,還有關于將重疊的間隔分成更小的部分。您必須經常使用Interval Arithmetic。


使用 Java 8,您可以首先將“術語”編碼為時間間隔,它本身就是Comparable. 如果用戶指定重疊的間隔,第二部分將把你的間隔分成多個。


class Interval implements Comparable<Interval> {

  private final LocalDateTime start;

  private final LocalDateTime end;


  public Interval(LocalDateTime start, LocalDateTime end) {

     this.start = start;

     this.end = end;

  }


  public int compareTo(Interval that) {

    return this.start.compareTo(that.start);

  }


  public boolean overlaps(Interval that) {

    return !this.isBefore(that) && !this.isAfter(that);

  }


  public boolean contains(Interval that) {

    return this.start.isBefore(that.start) && this.end.isAfter(that.end);

  }


  public boolean isBefore(Interval that) {

    return this.end.isBefore(that.start);

  }


  public boolean isAfter(Interval that) {

    return this.start.isAfter(that.end);

  }


  public Set<Interval> fragment(Interval that) {

    if (that.start.isBefore(this.start)) {

      return that.fragment(this);

    }


    Set<Interval> result = new HashSet<>();

    if (this.end.isBefore(that.start)) {

       result.add(this);

       result.add(that);

       result.add(new Interval(this.end, that.start));

    } else if ((this.end.isAfter(that.start) && this.end.isBefore(that.end)) {

       result.add(new Interval(this.start, that.start);

       result.add(new Interval(that.start, this.end);

       result.add(new Interval(this.end, that.end));

    } else if (this.end.isAfter(that.end)) {

       result.add(new Interval(this.start, that.start);

       result.add(new Interval(that);

       result.add(new Interval(that.end, this.end));

    }

  }

}

您現在可以對它們進行排序,因為Intervals 可以按開始日期進行比較。每當用戶輸入一個新的Interval(術語)時,您必須通過列表檢查它是否contains()存在間隔,或者它是否在它之前,使用isBefore()或isAfter()。如果它overlaps()你必須小心是否還要檢查它是否與列表中的下一個間隔重疊。


然后,您可以調用fragment()which 會將 2 個間隔組合成更小的間隔。您需要小心刪除以前的。因此,只需瀏覽列表并檢查它們是否重疊可能是有意義的。如果您到達終點,您仍然可以使用fragment()組合兩個不相交的間隔。


查看完整回答
反對 回復 2022-01-19
  • 3 回答
  • 0 關注
  • 190 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號