V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
godleon
V2EX  ›  程序员

请教个 Java list 处理数据的问题?

  •  
  •   godleon · 2023-12-18 10:44:04 +08:00 · 2816 次点击
    这是一个创建于 375 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题

    环境:java ,springboot , jdk8
    
    我现在有个 List<bean> beans ; bean 里有 2 个字段,aTime ,bTime , 都是 java.utile 包下 Date 类型;
    
    我现在的需求是, 我需要对比两个字段,有一个是最新的就在 list 的最前面;
    
    如:bean1 {aTime:2023-12-18 05:00:00 , bTime: 2023-12-18 10:40:00}
    
          bean2 {aTime:2023-12-18 04:00:00 , bTime: 2023-12-18 11:40:00}
    
          bean3 {aTime:2023-12-18 11:00:00 , bTime: 2023-12-18 03:40:00}
    

    那么 list 返回 顺序是 [bean2, bean3, bean1] 这种该怎么判断一下

    liprais
        1
    liprais  
       2023-12-18 10:50:27 +08:00
    Comparators
    提问之前先搜索
    godleon
        2
    godleon  
    OP
       2023-12-18 10:52:52 +08:00   ❤️ 3
    @liprais 这是啥东西
    chendy
        3
    chendy  
       2023-12-18 10:52:56 +08:00
    建议去写点 leetcode 入门题,这不就一排序么…

    ArrayList<X> xx = new ArrayList<>();
    xx.sort(Comparator.comparing(X::getA).thenComparing(X::getB));
    AlvaMu
        4
    AlvaMu  
       2023-12-18 10:55:46 +08:00
    实现 Comparator 接口,重写 compare 方法,用参数中的两个对象,先各自取出较大的 Date,然后两个对象之间的 Date 比较
    visper
        5
    visper  
       2023-12-18 10:58:51 +08:00
    直接问 chatgpt:java 中对 list 里面的 bean 按 bean 的 aTime 字段排序
    godleon
        6
    godleon  
    OP
       2023-12-18 11:04:51 +08:00
    @chendy 你可复现一下 是不对的
    xianyv
        7
    xianyv  
       2023-12-18 11:04:58 +08:00
    @godleon #2 建议直接百度
    JackCh3ng
        8
    JackCh3ng  
       2023-12-18 11:10:10 +08:00
    优先队列?
    JackCh3ng
        9
    JackCh3ng  
       2023-12-18 11:15:04 +08:00
    @JackCh3ng
    或者 Bean 实现 Comparator 自己比较也行啊,
    或者用 hutool 的 DateUtil 先把 Bean 里的 aTime 和 bTime 比较一下找到最新的,拿这个最新的和其他的 Bean 比较,sort 排序就行。
    脑子还是自己多动动比较好。
    chendy
        10
    chendy  
       2023-12-18 11:24:32 +08:00
    帮人帮到底了,说实话这帖子放十年前百度 java 吧我都直接删的,真就硬伸手啊
    xx.sort(Comparator.comparing(x -> {
    if (x.getA().compareTo(x.getB()) > 0) {
    return x.getA();
    } else {
    return x.getB();
    }
    }));
    XiFanL1
        11
    XiFanL1  
       2023-12-18 11:25:29 +08:00   ❤️ 1
    import java.util.*;
    import java.util.stream.Collectors;

    public class Bean {
    Date aTime;
    Date bTime;

    // getters and setters

    public Date getLatestTime() {
    return aTime.after(bTime) ? aTime : bTime;
    }
    }

    public class Main {
    public static void main(String[] args) {
    List<Bean> beans = new ArrayList<>();

    // add beans to the list

    List<Bean> sortedBeans = beans.stream()
    .sorted(Comparator.comparing(Bean::getLatestTime).reversed())
    .collect(Collectors.toList());

    // now sortedBeans is sorted by the latest time in each bean
    }
    }
    eddiechow
        12
    eddiechow  
       2023-12-18 11:26:56 +08:00
    @chendy 你这个是先按 atime 排,再按 btime 排; OP 的需求其实是按 atime 和 btime 两个时间比较的更新(更大)的时间降序排;
    不如这样吧,增加 xtime ,先对 list forEach 比较 atime 和 btime ,把更新的时间赋值到 xtime ,然后再对 xtime 降序排序即可,OP 可行?@godleon
    zydxn
        13
    zydxn  
       2023-12-18 11:27:09 +08:00
    楼上都直接帮你写出来了...

    推荐你看本书吧

    https://book.douban.com/subject/26346017/
    godleon
        14
    godleon  
    OP
       2023-12-18 11:30:21 +08:00
    @chendy 大哥 你能回显一下 在回帖吗?
    Kyle18Tang
        15
    Kyle18Tang  
       2023-12-18 11:31:36 +08:00
    @chendy #10 其实看你 3 楼写的思路,就算复现不了,作为一个开发人员也该知道怎么改了,而不是继续抱怨说复现不了。
    yazinnnn0
        16
    yazinnnn0  
       2023-12-18 11:31:39 +08:00
    list.sortBy {it -> minOf(it.a, it.b) }
    godleon
        17
    godleon  
    OP
       2023-12-18 11:31:44 +08:00
    @chendy 还是你真的理解不了 问题呢
    eddiechow
        18
    eddiechow  
       2023-12-18 11:32:14 +08:00
    @chendy #10 第二次的实际运行结果还是和需求不一致😂
    Ericcccccccc
        19
    Ericcccccccc  
       2023-12-18 11:32:25 +08:00
    搜 java 自定义结构体排序
    eddiechow
        20
    eddiechow  
       2023-12-18 11:35:54 +08:00
    其实,题目很简单,绝对的绝大多数 v 友都人为很简单,但往往在回答这种简单问题的准确答案时却会放一些简单的错(手滑、笔误、需求理解不清等等😂);(纯提供思路的除外)
    saveload
        21
    saveload  
       2023-12-18 11:46:07 +08:00
    我会三种写法,每月 8K 笑哈哈
    nauhc
        22
    nauhc  
       2023-12-18 11:46:34 +08:00
    11 楼把正确答案都写出来了
    darkengine
        23
    darkengine  
       2023-12-18 11:50:21 +08:00   ❤️ 6
    还是你真的理解不了 问题呢
    --------

    看到这句真绷不住了 😂
    zmal
        24
    zmal  
       2023-12-18 11:54:36 +08:00
    能上 V2EX ,去 gpt 问问也有答案了啊。
    silentsky
        25
    silentsky  
       2023-12-18 11:59:21 +08:00
    这个问题太简单 跳过
    NickX
        26
    NickX  
       2023-12-18 12:00:11 +08:00
    list 的排序,一楼已经说了,Comparators ,你想根据什么规则排都没问题。简单来说就是 a 和 b 时间取最大值再排序嘛。
    forgottencoast
        27
    forgottencoast  
       2023-12-18 12:01:55 +08:00
    @eddiechow
    真的,说明眼高手低的人很多。
    forgottencoast
        28
    forgottencoast  
       2023-12-18 12:05:17 +08:00
    @zydxn
    OP 不是看书的问题,OP 是缺乏基本的编程基础知识。
    这个就是最简单的按照行内元素的属性来排序,现代编程语言都会支持的排序。
    Alex5467
        29
    Alex5467  
       2023-12-18 12:06:57 +08:00 via iPhone
    @chendy lamada 表达式
    nerkeler
        30
    nerkeler  
       2023-12-18 12:11:43 +08:00
    这也不是眼高手低的问题,这题的实现思路就没什么难度,总而言之 你要先 给每个 bean 排好序取最新的日期,在用每个 bean 里的最新日期排序
    spike0100
        31
    spike0100  
       2023-12-18 13:19:17 +08:00 via iPhone
    按照 a 和 b 分别排序,然后对比两个集合的第一个对象就完了。
    wxw752
        32
    wxw752  
       2023-12-18 13:38:01 +08:00
    @eddiechow #20 10 楼无非就是从小到大排了,想从大到小加个 reversed()不就完事了。
    msaionyc
        33
    msaionyc  
       2023-12-18 13:45:12 +08:00
    personList.stream().
    sorted((a, b) -> (int) (Math.max(b.getaTime().getTime(), b.getbTime().getTime()) - Math.max(a.getaTime().getTime(), a.getbTime().getTime()))).
    collect(Collectors.toList());

    直接取 aTime 和 bTime 里的较大值去写 comparator 就可以了,验证过了,排序结果符合你的描述
    vagusss
        34
    vagusss  
       2023-12-18 13:50:20 +08:00
    有一个是最新的就在 list 的最前面,坦白说我没有看懂这句话,
    vagusss
        35
    vagusss  
       2023-12-18 13:51:53 +08:00
    @vagusss 有点懂了, 是取两个值中的最大值进行比较排序?
    twofox
        36
    twofox  
       2023-12-18 14:08:33 +08:00
    。。。看到这句真绷不住了 😂

    没学过 Comparators 吗
    28Sv0ngQfIE7Yloe
        37
    28Sv0ngQfIE7Yloe  
       2023-12-18 14:09:56 +08:00
    取 A 和 B 中最新的时间 X ,再按照 X 排下
    ZZ74
        38
    ZZ74  
       2023-12-18 14:13:34 +08:00
    @twofox
    绷不住了,看了 OP 回复 1 楼给的提示才是真的绷不住
    Goooooos
        39
    Goooooos  
       2023-12-18 14:16:01 +08:00
    一看就是期末考试题
    Navee
        40
    Navee  
       2023-12-18 14:22:41 +08:00
    有两个方法达到你想要的效果
    1. 你的 bean 实现接口:java.util.Comparator
    2. 使用 List.sort 方法,传入 Comparator 函数
    cpstar
        41
    cpstar  
       2023-12-18 14:31:39 +08:00
    恰巧在 compare 上,曾经遇到一个 BUG ,https://page.cpstar.cn/post/chu-li-yi-ge-yi-xiang-bu-dao-de-bug/,自己写 comparator ,要注意三性
    twofox
        42
    twofox  
       2023-12-18 14:43:26 +08:00   ❤️ 1
    @ZZ74 如果是我被一楼回复了,我肯定先滚去搜一下是啥玩意

    然后回来谢谢他,而不是这是啥玩意🤣
    c2const
        43
    c2const  
       2023-12-18 14:57:15 +08:00
    虽然工作中 Java 接触不多,虽然技术水平和薪资也无关,
    ---------------
    但突然感觉有的人确实不适合编程 :(
    或者说只是为了混个工作? :(
    broken123
        44
    broken123  
       2023-12-18 14:59:21 +08:00
    为何会问如此基础的问题?不先了解下排序的本质么
    supertailcat
        45
    supertailcat  
       2023-12-18 15:19:31 +08:00
    这种问题建议直接 LLM 。如果答案不对就说明你的描述能力太差了。而且不得不说,你题面这个描述确实太差了…
    lmq2582609
        46
    lmq2582609  
       2023-12-18 16:17:01 +08:00   ❤️ 2
    List<Bean> beans;
    beans.sort(
    Comparator.comparingLong((Bean bean) -> {
    //取 aTime 时间戳
    Date aTime = bean.getATime();
    //取 bTime 时间戳
    Date bTime = bean.getBTime();
    //取 aTime 和 bTime 中最新的时间(时间戳较大的就是最新的时间)
    return Math.max(aTime.getTime(), bTime.getTime());
    }).reversed() //加 reversed()是排倒序(从大到小)
    );
    希望可以帮到你!
    orionnnnn
        47
    orionnnnn  
       2023-12-18 16:42:06 +08:00
    @lmq2582609 好开!
    yeyang5211
        48
    yeyang5211  
       2023-12-18 16:55:55 +08:00
    请教问题的时候记得先把火气憋住,搞到答案了再怼. 轻重缓急晓得伐
    mazhiyuan
        49
    mazhiyuan  
       2023-12-18 17:31:05 +08:00
    @lmq2582609 学习了,指不定日后会用到,感谢。
    godleon
        50
    godleon  
    OP
       2023-12-19 14:49:31 +08:00
    @lmq2582609 首先谢谢回复,当 atime 和 btime 都不为 null 的时候 确实可以满足需求,但是我的需求里 现在 atime 和 btime 可能有一个会为 null, 当一个为 null 时,另一个日期继续参与排序,该怎么优化一下~
    lmq2582609
        51
    lmq2582609  
       2023-12-19 23:08:58 +08:00
    @godleon
    如果有 null 的情况,可以给一个默认值,如-1
    List<Bean> beans;
    beans.sort(
    Comparator.comparingLong((Bean bean) -> {
    //取 aTime 时间戳
    Date aTime = bean.getATime();
    //取 bTime 时间戳
    Date bTime = bean.getBTime();
    //取 aTime 和 bTime 中最新的时间(时间戳较大的就是最新的时间)
    return Math.max(getTime(aTime), getTime(bTime));
    }).reversed() //加 reversed()是排倒序(从大到小)
    );

    private long getTime(Date date) {
    return date == null ? -1 : date.getTime();
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2069 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 00:49 · PVG 08:49 · LAX 16:49 · JFK 19:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.