簡體   English   中英

無法添加邏輯以在 Java/android 中的現有比較器中使用日期進行排序

[英]Unable to add a logic to sort with dates in the existing comparator in Java/android

我想添加一個條件,該條件也根據 item.startReading 的 DATE(降序)進行排序。 item.startReading值具有字符串格式的日期值2018-10-20T12:05:41 但我不知道如何將此邏輯添加到當前代碼中。 在用戶點擊雜志或書籍項目之前, item.startReading值為null . 當用戶單擊其中一項時,我希望最新的item.startReading像下面這樣轉到頂部。 抱歉我的解釋,但自從我開始學習 java/android 以來,我真的需要知道該怎么做。 一些例子或提示會很可愛。 我很想聽聽你的意見。

  1. 雜志 (2018-10-21T13:06:41) 最新日期項目去頂部
  2. 雜志 (2018-10-20T12:05:41)
  3. 圖書
  4. 圖書

目前,我有以下比較器代碼可以進行如下排序。

(使用比較器之前)

  1. 雜志
  2. 圖書
  3. 雜志
  4. 圖書

(在使用比較器之后)用類型重新編碼,最后用 ID ↓

  1. 圖書
  2. 圖書
  3. 雜志
  4. 雜志

我的比較器代碼:

public Comparator<MyItem> myComparator = (item1, item2) -> {
    //How to add the desc date order with Dates?

    if (item1.typeInt == MyItemModel.TYPE_BOOK && item2.typeInt !=  MyItemModel.TYPE_BOOK) {
        return -1;
    } else if (item1.type !=  MyItemModel.TYPE_BOOK && item2.type ==  MyItemModel.TYPE_BOOK) {
        return 1;
    } else if (item1.type == MyItemModel.TYPE_MAGAZINE && item2.type != MyItemModel.TYPE_MAGAZINE) {
        return -1;
    } else if (item1.type != MyItemModel.TYPE_MAGAZINE && item2.type == MyItemModel.TYPE_MAGAZINE) {
        return 1;
    } 
    return (Integer.compare((int) item1.id, (int) item2.id)) * -1;
};

首先創建一個解析給定日期的函數

public Date parseDateFromString(String date){
    if(date == null) {
        return null;
    }
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-yy'T'HH:mm:ss", Locale.US);
    try {
        return simpleDateFormat.parse(date);
    } catch (ParseException e) {
        e.printStackTrace();
        return null;
    }
}

然后將其與 Comparator 進行比較

if (item1.typeInt != item2.typeInt) {
    return item1.typeInt == MyItemModel.TYPE_MAGAZINE ? 1 : -1;
} else {
    if (parseDateFromString(item1.getStartReading()) == null) {
        return 0;
    } else if (parseDateFromString(item2.getStartReading()) == null) {
        return -1;
    } else {
        return parseDateFromString(item2.getStartReading()).after(parseDateFromString(item1.getStartReading())) ? 1 : -1;
    }
}
public static Comparator<MyItem> myComparator
        // books first; sort by a Boolean expression that is false for books to put them first
        = Comparator.comparing((MyItem it) -> it.type != MyItemModel.TYPE_BOOK)
                // then magazines first
                .thenComparing(it -> it.type != MyItemModel.TYPE_MAGAZINE)
                // then by start date-time, nulls last, otherwise newest first
                .thenComparing(it -> it.startReading,
                        Comparator.nullsLast(Comparator.comparing((String start)
                                -> LocalDateTime.parse(start)).reversed()))
                // then by ID
                .thenComparing(it -> it.id);

由於您的 API 級別對於 lambda 來說足夠高,我假設您也可以使用Comparator.comparingthenComparing等。這樣做。 它不僅更簡潔,而且不易出錯。 我懷疑你預期的type ,而不是typeInt在你的代碼,至少它不是一致,不一致,你根本無法做comparing

Comparator.nullsLast最后對null值進行排序(如果您需要,還有一個姊妹方法nullsFirst )。 您的2018-10-21T13:06:41字符串采用 ISO 8601 格式, LocalDateTime將其解析為默認格式,即沒有任何顯式格式化程序。 我們當然應該利用這個事實。 reversed顛倒比較器的順序,因此最新的而不是最舊的項目首先出現。

編輯:從這個答案中獲得靈感,我正在對布爾值進行排序,以便首先獲取書籍和雜志。 在布爾值的自然順序中,假先於真。 我對it.type != MyItemModel.TYPE_BOOK排序,這對於書籍來說是錯誤的,也就是說,它們首先出現,對於其他一切都是正確的。 接下來我對雜志也做類似的事情。

進一步可能的改進

  • 為您的屬性聲明 getter 並使用MyItem::getId而不是it -> it.id
  • startReading存儲為LocalDateTime而不是MyItem的字符串,因此您不需要為每個比較進行解析(還有許多其他原因為什么這是一個好主意)。 當您需要將其呈現給用戶時,只需將其格式化為String

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM