JAVA实现多字段排序

1. 问题

如何用java实现sql里多字段排序, 如order by col1 desc, col2, col3 desc…

2. 场景

奥运会时期,每场赛事后,对国家的金、银、铜牌进行排序,排序规则如下:
先以金牌排序,金牌数越多,排得越前,如果金牌数相同,则比银牌数,如果银牌数一样多,则比铜牌数,如果铜牌数还一样多,则按国家英文字母顺序升序排序。
例如:
China 51 20 21
American 50 1 1
Japan 0 0 0
上面是三个国家的奖牌数,每一行依次是国家名、金牌数、银牌数、铜牌数。

3. 实现

3.1 实体class

public  class Medal {
        private String country; // 国家
        private int gi; // 金牌数量
        private int si; // 银牌数量
        private int bi; // 铜牌数量

        public Medal() {
        }

        public Medal(String country, int gi, int si, int bi) {
            this.country = country;
            this.gi = gi;
            this.si = si;
            this.bi = bi;
        }

        public String getCountry() {
            return country;
        }

        public int getGi() {
            return gi;
        }

        public int getSi() {
            return si;
        }

        public int getBi() {
            return bi;
        }
    }

3.2 方案1 使用单个Comparator实现

    /**
     * 使用单个比较器进行多字段排序
     * @param medalList
     * @return
     */
    public  static List<String> rankBySingleComparator(List<Medal> medalList){
        Collections.sort(medalList,(medal1,medal2)->{
            //第一排序字段
            if(medal1.getGi()!=medal2.getGi()){
                return medal2.getGi()-medal1.getGi(); //若要正序,交互medal1和medal2的位置即可
            }
            //第二排序字段
            if(medal1.getSi()!=medal2.getSi()){
                return medal2.getSi()-medal1.getSi(); //若要正序,交互medal1和medal2的位置即可
            }
            //第三排序字段
            if(medal1.getBi()!=medal2.getBi()){
                return medal2.getBi()-medal1.getBi(); //若要正序,交互medal1和medal2的位置即可
            }
            //第四排序字段
           return medal1.getCountry().compareTo(medal1.getCountry()); //若要倒序,交互medal1和medal2的位置即可
        });
        return medalList.stream().map(Medal::getCountry).collect(Collectors.toList());
    }
    

3.3 方案2 使用stream实现

/**
     * 使用Stream进行多字段排序
     *
     * @param medalList
     * @return
     */
    public static List<String> rankByStream(List<Medal> medalList) {
        return medalList.stream().sorted(Comparator.comparing(Medal::getGi, Comparator.reverseOrder())
                .thenComparing(Medal::getSi, Comparator.reverseOrder())
                .thenComparing(Medal::getBi, Comparator.reverseOrder())
                .thenComparing(Medal::getCountry)).map(Medal::getCountry).collect(Collectors.toList());
    }

3.3 验证

   public static void main(String[] args) {
        List<Medal> list1 = new ArrayList<>();
        list1.add(new Medal("China",51,20,21));
        list1.add(new Medal("American",50,1,1));
        list1.add(new Medal("Japan",0,0,0));
        List<String> expected1 = Arrays.asList("China", "American", "Japan");
        Assert.isTrue(expected1.equals(rankByStream(list1)),"rankByStream error");
        Assert.isTrue(expected1.equals(rankBySingleComparator(list1)),"rankByStream error");

        List<Medal> list2 = new ArrayList<>();
        list2.add(new Medal("China",51,20,21));
        list2.add(new Medal("American",52,1,1));
        list2.add(new Medal("Japan",0,0,0));
        List<String> expected2 = Arrays.asList("American", "China", "Japan");
        Assert.isTrue(expected2.equals(rankByStream(list2)),"rankByStream error");
        Assert.isTrue(expected2.equals(rankBySingleComparator(list2)),"rankByStream error");

        List<Medal> list3 = new ArrayList<>();
        list3.add(new Medal("China",51,20,21));
        list3.add(new Medal("American",51,20,22));
        list3.add(new Medal("Japan",53,0,0));
        List<String> expected3 = Arrays.asList("Japan", "American", "China");
        Assert.isTrue(expected3.equals(rankByStream(list3)),"rankByStream error");
        Assert.isTrue(expected3.equals(rankBySingleComparator(list3)),"rankByStream error");

        List<Medal> list4 = new ArrayList<>();
        list4.add(new Medal("China",51,20,21));
        list4.add(new Medal("American",50,1,1));
        list4.add(new Medal("Japan",0,0,0));
        list4.add(new Medal("France",51,20,20));
        List<String> expected4 = Arrays.asList("China", "France", "American", "Japan");
        Assert.isTrue(expected4.equals(rankByStream(list4)),"rankByStream error");
        Assert.isTrue(expected4.equals(rankBySingleComparator(list4)),"rankByStream error");
    }

参考
[1]: https://www.cnblogs.com/qujiayuan/p/12902380.html

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值