1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Java中List排序的3種方法!

        共 14351字,需瀏覽 29分鐘

         ·

        2022-07-13 13:08

        作者 | 王磊

        來(lái)源 | Java中文社群(ID:javacn666)

        轉(zhuǎn)載請(qǐng)聯(lián)系授權(quán)(微信ID:GG_Stone)

        在某些特殊的場(chǎng)景下,我們需要在 Java 程序中對(duì) List 集合進(jìn)行排序操作。比如從第三方接口中獲取所有用戶的列表,但列表默認(rèn)是以用戶編號(hào)從小到大進(jìn)行排序的,而我們的系統(tǒng)需要按照用戶的年齡從大到小進(jìn)行排序,這個(gè)時(shí)候,我們就需要對(duì) List 集合進(jìn)行自定義排序操作了。

        List 排序的常見(jiàn)方法有以下 3 種:

        1. 使用 Comparable 進(jìn)行排序;
        2. 使用 Comparator 進(jìn)行排序;
        3. 如果是 JDK 8 以上的環(huán)境,也可以使用 Stream 流進(jìn)行排序。

        下面我們分別來(lái)看各種排序方法的具體實(shí)現(xiàn)。

        1.使用 Comparable 排序

        按照本文設(shè)計(jì)的場(chǎng)景,我們需要?jiǎng)?chuàng)建一個(gè)包含了用戶列表的 List 集合,并按用戶的年齡從大到小進(jìn)行排序,具體實(shí)現(xiàn)代碼如下:

        public class ListSortExample {
            public static void main(String[] args) {
                // 創(chuàng)建并初始化 List
                List<Person> list = new ArrayList<Person>() {{
                    add(new Person(1, 30, "北京"));
                    add(new Person(2, 20, "西安"));
                    add(new Person(3, 40, "上海"));
                }};
                // 使用 Comparable 自定的規(guī)則進(jìn)行排序
                Collections.sort(list);
                // 打印 list 集合
                list.forEach(p -> {
                    System.out.println(p);
                });
            }
        }

        //  以下 set/get/toString 使用的是 lombok 的注解
        @Getter
        @Setter
        @ToString
        class Person implements Comparable<Person{
            private int id;
            private int age;
            private String name;

            public Person(int id, int age, String name) {
                this.id = id;
                this.age = age;
                this.name = name;
            }

            @Override
            public int compareTo(Person p) {
                return p.getAge() - this.getAge();
            }
        }

        以上代碼的執(zhí)行結(jié)果,如下圖所示:本方法的核心代碼如下:

        2.使用 Comparator 排序

        Comparable 是類內(nèi)部的比較方法,而 Comparator 是排序類外部的比較器。使用 Comparator 比較器,無(wú)需修改原 Person 類,只需要擴(kuò)充一個(gè) Person 類的比較器就行了,Comparator 的實(shí)現(xiàn)方法有以下兩種:

        • 新建 Comparator 比較器;
        • 使用 Comparator 匿名類比較器。

        其中,第二種實(shí)現(xiàn)方法要更簡(jiǎn)潔一些,我們通過(guò)下面的具體代碼,來(lái)觀察一下二者的區(qū)別。

        2.1 新建 Comparator 比較器

        public class ListSortExample2 {
            public static void main(String[] args) {
                // 創(chuàng)建并初始化 List
                List<Person> list = new ArrayList<Person>() {{
                    add(new Person(1, 30, "北京"));
                    add(new Person(2, 20, "西安"));
                    add(new Person(3, 40, "上海"));
                }};
                // 使用 Comparator 比較器排序
                Collections.sort(list, new PersonComparator());
                // 打印 list 集合
                list.forEach(p -> {
                    System.out.println(p);
                });
            }
        }
        /**
         * 新建 Person 比較器
         */

        class PersonComparator implements Comparator<Person{
            @Override
            public int compare(Person p1, Person p2) {
                return p2.getAge() - p1.getAge();
            }
        }
        @Getter
        @Setter
        @ToString
        class Person {
            private int id;
            private int age;
            private String name;

            public Person(int id, int age, String name) {
                this.id = id;
                this.age = age;
                this.name = name;
            }
        }

        以上代碼的執(zhí)行結(jié)果,如下圖所示:本方法的核心實(shí)現(xiàn)代碼如下:

        2.2 匿名類比較器

        比較器 Comparator 可以使用更簡(jiǎn)潔的匿名類的方式,來(lái)實(shí)現(xiàn)排序功能,具體實(shí)現(xiàn)代碼如下:

        public class ListSortExample2 {
            public static void main(String[] args) {
                // 創(chuàng)建并初始化 List
                List<Person> list = new ArrayList<Person>() {{
                    add(new Person(1, 30, "北京"));
                    add(new Person(2, 20, "西安"));
                    add(new Person(3, 40, "上海"));
                }};
                // 使用匿名比較器排序
                Collections.sort(list, new Comparator<Person>() {
                    @Override
                    public int compare(Person p1, Person p2) {
                        return p2.getAge() - p1.getAge();
                    }
                });
                // 打印 list 集合
                list.forEach(p -> {
                    System.out.println(p);
                });
            }
        }
        @Getter
        @Setter
        @ToString
        class Person {
            private int id;
            private int age;
            private String name;
            public Person(int id, int age, String name) {
                this.id = id;
                this.age = age;
                this.name = name;
            }
        }

        以上代碼的執(zhí)行結(jié)果,如下圖所示:

        3.使用 Stream 流排序

        在 JDK 8 之后可以使用更加簡(jiǎn)單的方法 Stream 流來(lái)實(shí)現(xiàn)排序功能,它的實(shí)現(xiàn)只需要一行代碼,具體實(shí)現(xiàn)如下:

        public class ListSortExample3 {
            public static void main(String[] args) {
                // 創(chuàng)建并初始化 List
                List<Person> list = new ArrayList<Person>() {{
                    add(new Person(1, 30, "北京"));
                    add(new Person(2, 20, "西安"));
                    add(new Person(3, 40, "上海"));
                }};
                // 使用 Stream 排序
                list = list.stream().sorted(Comparator.comparing(Person::getAge).reversed())
                        .collect(Collectors.toList());
                // 打印 list 集合
                list.forEach(p -> {
                    System.out.println(p);
                });
            }
            @Getter
            @Setter
            @ToString
            static class Person {
                private int id;
                private int age;
                private String name;
                public Person(int id, int age, String name) {
                    this.id = id;
                    this.age = age;
                    this.name = name;
                }
            }
        }

        其中 reversed() 表示倒序的意思,如果不使用此方法則是正序。

        以上代碼的執(zhí)行結(jié)果,如下圖所示:

        擴(kuò)展:排序字段為 null

        使用 Stream 進(jìn)行排序時(shí),如果排序的字段出現(xiàn) null 值就會(huì)導(dǎo)致異常發(fā)生,具體示例如下:

        public class ListSortExample4 {
            public static void main(String[] args) {
                // 創(chuàng)建并初始化 List
                List<Person> list = new ArrayList<Person>() {{
                    add(new Person(30, "北京"));
                    add(new Person(10, "西安"));
                    add(new Person(40, "上海"));
                    add(new Person(null, "上海")); // 年齡為 null 值
                }};
                // 按照[年齡]正序,但年齡中有一個(gè) null 值
                list = list.stream().sorted(Comparator.comparing(Person::getAge))
                        .collect(Collectors.toList());
                // 打印 list 集合
                list.forEach(p -> {
                    System.out.println(p);
                });
            }
        }
        @Getter
        @Setter
        @ToString
        class Person {
            private Integer age;
            private String name;

            public Person(Integer age, String name) {
                this.age = age;
                this.name = name;
            }
        }

        以上代碼的執(zhí)行結(jié)果,如下圖所示:想要解決上述問(wèn)題,需要給 Comparator.comparing 傳遞第二個(gè)參數(shù):Comparator.nullsXXX,如下代碼所示:

        public class ListSortExample4 {
            public static void main(String[] args) {
                // 創(chuàng)建并初始化 List
                List<Person> list = new ArrayList<Person>() {{
                    add(new Person(30, "北京"));
                    add(new Person(10, "西安"));
                    add(new Person(40, "上海"));
                    add(new Person(null, "上海"));
                }};
                // 按照[年齡]正序,但年齡中有一個(gè) null 值
                list = list.stream().sorted(Comparator.comparing(Person::getAge,
                        Comparator.nullsFirst(Integer::compareTo)))
                        .collect(Collectors.toList());
                // 打印 list 集合
                list.forEach(p -> {
                    System.out.println(p);
                });
            }
        }
        @Getter
        @Setter
        @ToString
        class Person {
            private Integer age;
            private String name;

            public Person(Integer age, String name) {
                this.age = age;
                this.name = name;
            }
        }

        Comparator.nullsFirst 表示將排序字段中的 null 值放到集合最前面,如果想要將 null 值放到集合最后面可以使用 Comparator.nullsLast。

        以上代碼的執(zhí)行結(jié)果,如下圖所示:

        總結(jié)

        本文介紹了 3 種 List 排序的方法,前兩種方法常用于 JDK 8 之前的版本,其中比較器 Comparator 有兩種實(shí)現(xiàn)的寫法,而在 JDK 8 之后的版本,就可以使用 Comparator.comparing 實(shí)現(xiàn)排序了,如果排序字段中可能出現(xiàn) null 值,要使用 Comparator.nullsXXX 進(jìn)行排序處理(否則會(huì)報(bào)錯(cuò))。

        w3cschool編程獅


        專門幫助零基礎(chǔ)的同學(xué)們學(xué)習(xí)編程基礎(chǔ)的學(xué)習(xí)網(wǎng)站


        同時(shí),也歡迎各位朋友們添加我們學(xué)習(xí)顧問(wèn)的微信 ↓,可以領(lǐng)取10G免費(fèi)學(xué)習(xí)資料包,也可以申請(qǐng)加入學(xué)習(xí)交流群(包括前端、Python、Java、Php、C、小程序、數(shù)據(jù)庫(kù)等)。


        編程獅學(xué)習(xí)顧問(wèn)-七七

        添加時(shí)請(qǐng)備注(咨詢

        如果您覺(jué)得本篇文章還不錯(cuò)
        請(qǐng)多多支持一下我們
        點(diǎn)贊、在線、分享三連鼓勵(lì)一下
        瀏覽 45
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            日韩综合 | 丝袜制服影音先锋 | 在线播放 神尾舞 | xxxx18日本高清hd老师 | 妓女卖婬一区二区三区在线观看 | 成年人毛片视频 | 成人网址在线看 | 国内精品国产成人三级 | cao死你个小sao货湿透了视频 | 小妖精抬起臀嗯啊喷水h视频 |