<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java中List排序的3種方法!

          共 6322字,需瀏覽 13分鐘

           ·

          2021-12-28 20:12

          作者 | 王磊

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

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

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

          List 排序的常見方法有以下 3 種:

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

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

          1.使用 Comparable 排序

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

          public?class?ListSortExample?{
          ????public?static?void?main(String[]?args)?{
          ????????//?創(chuàng)建并初始化?List
          ????????List?list?=?new?ArrayList()?{{
          ????????????add(new?Person(1,?30,?"北京"));
          ????????????add(new?Person(2,?20,?"西安"));
          ????????????add(new?Person(3,?40,?"上海"));
          ????????}};
          ????????//?使用?Comparable?自定的規(guī)則進行排序
          ????????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 比較器,無需修改原 Person 類,只需要擴充一個 Person 類的比較器就行了,Comparator 的實現(xiàn)方法有以下兩種:

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

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

          2.1 新建 Comparator 比較器

          public?class?ListSortExample2?{
          ????public?static?void?main(String[]?args)?{
          ????????//?創(chuàng)建并初始化?List
          ????????List?list?=?new?ArrayList()?{{
          ????????????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é)果,如下圖所示:本方法的核心實現(xiàn)代碼如下:

          2.2 匿名類比較器

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

          public?class?ListSortExample2?{
          ????public?static?void?main(String[]?args)?{
          ????????//?創(chuàng)建并初始化?List
          ????????List?list?=?new?ArrayList()?{{
          ????????????add(new?Person(1,?30,?"北京"));
          ????????????add(new?Person(2,?20,?"西安"));
          ????????????add(new?Person(3,?40,?"上海"));
          ????????}};
          ????????//?使用匿名比較器排序
          ????????Collections.sort(list,?new?Comparator()?{
          ????????????@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 之后可以使用更加簡單的方法 Stream 流來實現(xiàn)排序功能,它的實現(xiàn)只需要一行代碼,具體實現(xiàn)如下:

          public?class?ListSortExample3?{
          ????public?static?void?main(String[]?args)?{
          ????????//?創(chuàng)建并初始化?List
          ????????List?list?=?new?ArrayList()?{{
          ????????????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é)果,如下圖所示:

          擴展:排序字段為 null

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

          public?class?ListSortExample4?{
          ????public?static?void?main(String[]?args)?{
          ????????//?創(chuàng)建并初始化?List
          ????????List?list?=?new?ArrayList()?{{
          ????????????add(new?Person(30,?"北京"));
          ????????????add(new?Person(10,?"西安"));
          ????????????add(new?Person(40,?"上海"));
          ????????????add(new?Person(null,?"上海"));?//?年齡為?null?值
          ????????}};
          ????????//?按照[年齡]正序,但年齡中有一個?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é)果,如下圖所示:想要解決上述問題,需要給 Comparator.comparing 傳遞第二個參數(shù):Comparator.nullsXXX,如下代碼所示:

          public?class?ListSortExample4?{
          ????public?static?void?main(String[]?args)?{
          ????????//?創(chuàng)建并初始化?List
          ????????List?list?=?new?ArrayList()?{{
          ????????????add(new?Person(30,?"北京"));
          ????????????add(new?Person(10,?"西安"));
          ????????????add(new?Person(40,?"上海"));
          ????????????add(new?Person(null,?"上海"));
          ????????}};
          ????????//?按照[年齡]正序,但年齡中有一個?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 有兩種實現(xiàn)的寫法,而在 JDK 8 之后的版本,就可以使用 Comparator.comparing 實現(xiàn)排序了,如果排序字段中可能出現(xiàn) null 值,要使用 Comparator.nullsXXX 進行排序處理(否則會報錯)。





          0、重磅!兩萬字長文總結(jié),梳理 Java 入門進階哪些事(推薦收藏)

          1、30歲生日,總結(jié)過去的一年,我哭了……

          2、看完這設(shè)計模式匯總,你確定不加收藏嗎


          瀏覽 58
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  网站日逼| 风韵十足的良家美少妇酒店偷情 | 中文字幕一区二区久久人妻网站 | 熟女视频一区二区三区国产 | 日韩激情综合网 |