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

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

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

    问题

    环境: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] 这种该怎么判断一下

    F281M6Dh8DXpD1g2
        1
    F281M6Dh8DXpD1g2  
       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 分别排序,然后对比两个集合的第一个对象就完了。
    rockddd
        32
    rockddd  
       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 。如果答案不对就说明你的描述能力太差了。而且不得不说,你题面这个描述确实太差了…
    dongdong12345
        46
    dongdong12345  
       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 时,另一个日期继续参与排序,该怎么优化一下~
    dongdong12345
        51
    dongdong12345  
       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     Solana     883 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 21:21 PVG 05:21 LAX 13:21 JFK 16:21
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86