V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wuwudeqi
V2EX  ›  Java

Java list 排列

  •  
  •   wuwudeqi · 2020-01-10 14:02:04 +08:00 · 3030 次点击
    这是一个创建于 1540 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有个 list<object>,里面放了不同的消息对象 但是不同对象之间都有 isRead 字段和 createTime 字段,isRead 就是未读已读 createTime 就是创建时间 按照未读在前,已读在后,未读和已读里面按照 createTime 排列,新的消息在前,旧的消息在后,v 友们有思路么

    </object>

    23 条回复    2020-01-11 12:15:48 +08:00
    spritewdx
        1
    spritewdx  
       2020-01-10 14:27:46 +08:00
    把已读,未读区分开,写个根据 createTime 的比较器,分别用比较器进行排序,排序后合并
    bluehr
        2
    bluehr  
       2020-01-10 14:29:57 +08:00
    1l 正解
    zilaijuan
        3
    zilaijuan  
       2020-01-10 14:32:17 +08:00 via Android
    @spritewdx 比较器里先按已读未读比较,再按时间比较不行吗?为啥非要先分开?
    nutting
        4
    nutting  
       2020-01-10 14:34:44 +08:00
    还真没搞过两个条件比较的,测试一下吧
    Raymon111111
        5
    Raymon111111  
       2020-01-10 14:35:32 +08:00
    两个条件的比较器, 搜一下就有.
    l8g
        6
    l8g  
       2020-01-10 14:36:10 +08:00
    如果你能抽出一个父类,实现 Comparable 接口,就非常简单了。
    muyiluop
        7
    muyiluop  
       2020-01-10 14:38:30 +08:00
    我猜可以:时间字段转为时间戳,根据是否已读判断,已读的时间字段设置成负数之后正序排,未读的正常倒序排序。
    spritewdx
        8
    spritewdx  
       2020-01-10 14:39:21 +08:00
    @zilaijuan 没试过两个条件比较器,事实上很少用比较器
    qiyuey
        9
    qiyuey  
       2020-01-10 14:45:54 +08:00
    Compare 有 andThen
    qiyuey
        10
    qiyuey  
       2020-01-10 14:47:01 +08:00   ❤️ 1
    `Comparator.comparing(A::isRead).thenComparing(A::createTime)`
    dallaslu
        11
    dallaslu  
       2020-01-10 14:52:33 +08:00
    把 Bean 抽象为含有 isRead 和 createTime 的接口 MailBoxItem。实现 Comparable 或在外部实现 Comparator。

    ```java
    @Override
    public int compare(MailBoxItem o1, MailBoxItem o2) {
    if (!o2.isRead() && o1.isRead()) {
    return -1;
    } else if (o2.isRead() && !o1.isRead()) {
    return 1;
    } else {
    return o1.getCreatTime() - o2.getCreateTime();
    }
    }
    ```
    wuwudeqi
        12
    wuwudeqi  
    OP
       2020-01-10 15:18:29 +08:00
    @dallaslu 感谢思路~
    busfool
        13
    busfool  
       2020-01-10 15:27:04 +08:00 via Android
    第三方库有这种,搜搜 multi comparator
    fatpower
        14
    fatpower  
       2020-01-10 15:35:38 +08:00
    hutool
    collutil groupby 方法
    vanillaxxx
        15
    vanillaxxx  
       2020-01-10 16:25:50 +08:00
    val sorted = list.sortedWith(compareByDescending(Message::isRead).thenBy(Message:createTime))
    lihongjie0209
        16
    lihongjie0209  
       2020-01-10 16:28:20 +08:00
    @qiyuey #10 正解
    vanillaxxx
        17
    vanillaxxx  
       2020-01-10 16:32:44 +08:00
    @parorisim #15
    未读在前就是 isRead==false 的时候在前,这是一个倒序
    createTime 应该也是倒序

    纠正一下上面:
    compareByDescending(Message::isRead).thenByDescending(Message:createTime)
    Kiana1
        18
    Kiana1  
       2020-01-10 16:37:27 +08:00
    先分组 再排列
    list.stream().collect(Collectors.groupingBy(Message::isRead,Collectors.toList())).forEach((isRead,list)->{
    List<Message> collect = list.stream().sorted(Comparator.comparing(Message::getGmtBeginTime).reversed()).collect(Collectors.toList());
    });
    KentY
        19
    KentY  
       2020-01-10 23:25:46 +08:00
    不管已读那个 flag, 就整个按时间排序 ,随便你用 ascending or descending, 然后 filter 出来 the boolean true/false 连接起来就好了
    aguesuka
        20
    aguesuka  
       2020-01-11 11:10:01 +08:00 via Android
    9 楼正解,不要管其他得方法
    zunceng
        21
    zunceng  
       2020-01-11 11:11:45 +08:00
    Golang interface 最佳实践之一
    aguesuka
        22
    aguesuka  
       2020-01-11 11:12:16 +08:00 via Android
    楼上这么多答案水平堪忧
    yinzhili
        23
    yinzhili  
       2020-01-11 12:15:48 +08:00
    先分组,再排序。
    Collectors.groupingBy
    Comparator.comparing
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2884 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 13:06 · PVG 21:06 · LAX 06:06 · JFK 09:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.