首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法在Java/android中添加与现有比较器中的日期排序的逻辑

无法在Java/android中添加与现有比较器中的日期排序的逻辑
EN

Stack Overflow用户
提问于 2018-10-04 11:02:30
回答 2查看 110关注 0票数 2

我想添加一个条件,它还可以根据item.startReading的日期(降序)进行排序。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. books
  4. books

目前,我有下面的比较器代码来进行排序,如下所示。

(使用比较器之前)

  1. magazine
  2. books
  3. magazine
  4. books

(在使用比较器之后) reoders的类型,最后是ID↓

  • books

  • magazine

  • magazine

  1. 书籍

我的比较程序代码:

代码语言:javascript
复制
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;
};
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-04 11:42:12

首先创建一个解析给定日期的函数

代码语言:javascript
复制
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;
    }
}

然后与比较器进行比较,比如

代码语言:javascript
复制
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;
    }
}
票数 1
EN

Stack Overflow用户

发布于 2018-10-04 16:06:28

代码语言:javascript
复制
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.nullsLastnull值排在最后(如果您需要的话,还有一个姊妹方法nullsFirst )。您的2018-10-21T13:06:41字符串为ISO8601格式,即LocalDateTime解析为其默认格式的格式,即没有任何显式格式化程序。我们当然应该利用这一事实。reversed颠倒了比较器的顺序,因此最新的项而不是最旧的项首先出现。

编辑:在this answer的启发下,我正在对布尔值进行排序,首先是书籍,然后是杂志。在布尔值的自然顺序中,假在真之前。我对it.type != MyItemModel.TYPE_BOOK进行排序,这对于书籍来说是错误的,也就是说,它们是第一位的,对于其他所有东西都是正确的。接下来,我将对杂志执行类似的操作。

进一步可能的改进

  • 为您的属性声明getter,并在MyItem中使用MyItem::getId而不是startReading作为LocalDateTime而不是字符串,这样您就不需要为每个比较进行解析(这是一个好主意还有许多其他原因)。当您需要将其呈现给用户时,只需将其格式化为String
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52638352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档