自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java中List排序的三種方法!

開發(fā) 后端
從第三方接口中獲取所有用戶的列表,但列表默認是以用戶編號從小到大進行排序的,而我們的系統(tǒng)需要按照用戶的年齡從大到小進行排序,這個時候,我們就需要對 List 集合進行自定義排序操作了。

作者 | 王磊

來源 | 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)代碼如下:

  1. public class ListSortExample { 
  2.     public static void main(String[] args) { 
  3.         // 創(chuàng)建并初始化 List 
  4.         List<Person> list = new ArrayList<Person>() {{ 
  5.             add(new Person(1, 30, "北京")); 
  6.             add(new Person(2, 20, "西安")); 
  7.             add(new Person(3, 40, "上海")); 
  8.         }}; 
  9.         // 使用 Comparable 自定的規(guī)則進行排序 
  10.         Collections.sort(list); 
  11.         // 打印 list 集合 
  12.         list.forEach(p -> { 
  13.             System.out.println(p); 
  14.         }); 
  15.     } 
  16.  
  17. //  以下 set/get/toString 使用的是 lombok 的注解 
  18. @Getter 
  19. @Setter 
  20. @ToString 
  21. class Person implements Comparable<Person> { 
  22.     private int id; 
  23.     private int age; 
  24.     private String name
  25.  
  26.     public Person(int id, int age, String name) { 
  27.         this.id = id; 
  28.         this.age = age; 
  29.         this.name = name
  30.     } 
  31.  
  32.     @Override 
  33.     public int compareTo(Person p) { 
  34.         return p.getAge() - this.getAge(); 
  35.     } 

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

本方法的核心代碼如下:

2.使用 Comparator 排序

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

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

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

2.1 新建 Comparator 比較器

  1. public class ListSortExample2 { 
  2.     public static void main(String[] args) { 
  3.         // 創(chuàng)建并初始化 List 
  4.         List<Person> list = new ArrayList<Person>() {{ 
  5.             add(new Person(1, 30, "北京")); 
  6.             add(new Person(2, 20, "西安")); 
  7.             add(new Person(3, 40, "上海")); 
  8.         }}; 
  9.         // 使用 Comparator 比較器排序 
  10.         Collections.sort(list, new PersonComparator()); 
  11.         // 打印 list 集合 
  12.         list.forEach(p -> { 
  13.             System.out.println(p); 
  14.         }); 
  15.     } 
  16. /** 
  17.  * 新建 Person 比較器 
  18.  */ 
  19. class PersonComparator implements Comparator<Person> { 
  20.     @Override 
  21.     public int compare(Person p1, Person p2) { 
  22.         return p2.getAge() - p1.getAge(); 
  23.     } 
  24. @Getter 
  25. @Setter 
  26. @ToString 
  27. class Person { 
  28.     private int id; 
  29.     private int age; 
  30.     private String name
  31.  
  32.     public Person(int id, int age, String name) { 
  33.         this.id = id; 
  34.         this.age = age; 
  35.         this.name = name
  36.     } 

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

本方法的核心實現(xiàn)代碼如下:

 

2.2 匿名類比較器

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

  1. public class ListSortExample2 { 
  2.     public static void main(String[] args) { 
  3.         // 創(chuàng)建并初始化 List 
  4.         List<Person> list = new ArrayList<Person>() {{ 
  5.             add(new Person(1, 30, "北京")); 
  6.             add(new Person(2, 20, "西安")); 
  7.             add(new Person(3, 40, "上海")); 
  8.         }}; 
  9.         // 使用匿名比較器排序 
  10.         Collections.sort(list, new Comparator<Person>() { 
  11.             @Override 
  12.             public int compare(Person p1, Person p2) { 
  13.                 return p2.getAge() - p1.getAge(); 
  14.             } 
  15.         }); 
  16.         // 打印 list 集合 
  17.         list.forEach(p -> { 
  18.             System.out.println(p); 
  19.         }); 
  20.     } 
  21. @Getter 
  22. @Setter 
  23. @ToString 
  24. class Person { 
  25.     private int id; 
  26.     private int age; 
  27.     private String name
  28.     public Person(int id, int age, String name) { 
  29.         this.id = id; 
  30.         this.age = age; 
  31.         this.name = name
  32.     } 

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

3.使用 Stream 流排序

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

  1. public class ListSortExample3 { 
  2.     public static void main(String[] args) { 
  3.         // 創(chuàng)建并初始化 List 
  4.         List<Person> list = new ArrayList<Person>() {{ 
  5.             add(new Person(1, 30, "北京")); 
  6.             add(new Person(2, 20, "西安")); 
  7.             add(new Person(3, 40, "上海")); 
  8.         }}; 
  9.         // 使用 Stream 排序 
  10.         list = list.stream().sorted(Comparator.comparing(Person::getAge).reversed()) 
  11.                 .collect(Collectors.toList()); 
  12.         // 打印 list 集合 
  13.         list.forEach(p -> { 
  14.             System.out.println(p); 
  15.         }); 
  16.     } 
  17.     @Getter 
  18.     @Setter 
  19.     @ToString 
  20.     static class Person { 
  21.         private int id; 
  22.         private int age; 
  23.         private String name
  24.         public Person(int id, int age, String name) { 
  25.             this.id = id; 
  26.             this.age = age; 
  27.             this.name = name
  28.         } 
  29.     } 

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

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

擴展:排序字段為 null

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

  1. public class ListSortExample4 { 
  2.     public static void main(String[] args) { 
  3.         // 創(chuàng)建并初始化 List 
  4.         List<Person> list = new ArrayList<Person>() {{ 
  5.             add(new Person(30, "北京")); 
  6.             add(new Person(10, "西安")); 
  7.             add(new Person(40, "上海")); 
  8.             add(new Person(null"上海")); // 年齡為 null 值 
  9.         }}; 
  10.         // 按照[年齡]正序,但年齡中有一個 null 值 
  11.         list = list.stream().sorted(Comparator.comparing(Person::getAge)) 
  12.                 .collect(Collectors.toList()); 
  13.         // 打印 list 集合 
  14.         list.forEach(p -> { 
  15.             System.out.println(p); 
  16.         }); 
  17.     } 
  18. @Getter 
  19. @Setter 
  20. @ToString 
  21. class Person { 
  22.     private Integer age; 
  23.     private String name
  24.  
  25.     public Person(Integer age, String name) { 
  26.         this.age = age; 
  27.         this.name = name
  28.     } 

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

想要解決上述問題,需要給 Comparator.comparing 傳遞第二個參數(shù):Comparator.nullsXXX,如下代碼所示:

  1. public class ListSortExample4 { 
  2.     public static void main(String[] args) { 
  3.         // 創(chuàng)建并初始化 List 
  4.         List<Person> list = new ArrayList<Person>() {{ 
  5.             add(new Person(30, "北京")); 
  6.             add(new Person(10, "西安")); 
  7.             add(new Person(40, "上海")); 
  8.             add(new Person(null"上海")); 
  9.         }}; 
  10.         // 按照[年齡]正序,但年齡中有一個 null 值 
  11.         list = list.stream().sorted(Comparator.comparing(Person::getAge, 
  12.                 Comparator.nullsFirst(Integer::compareTo))) 
  13.                 .collect(Collectors.toList()); 
  14.         // 打印 list 集合 
  15.         list.forEach(p -> { 
  16.             System.out.println(p); 
  17.         }); 
  18.     } 
  19. @Getter 
  20. @Setter 
  21. @ToString 
  22. class Person { 
  23.     private Integer age; 
  24.     private String name
  25.  
  26.     public Person(Integer age, String name) { 
  27.         this.age = age; 
  28.         this.name = name
  29.     } 

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 進行排序處理(否則會報錯)。

 

責任編輯:姜華 來源: Java中文社群
相關(guān)推薦

2023-08-15 08:01:07

Go 語言排序

2009-07-08 12:56:32

編寫Servlet

2010-09-08 13:29:48

CSS

2016-10-12 13:53:38

JavaByteBufferRandomAcces

2022-05-31 16:00:46

Go 編程語言復制文件Go 標準庫

2009-12-11 18:49:39

預算編制博科資訊

2011-04-18 15:32:45

游戲測試測試方法軟件測試

2023-08-14 17:58:13

RequestHTTP請求

2024-11-15 07:00:00

Python發(fā)送郵件

2010-09-14 15:10:49

CSS注釋

2022-07-13 16:06:16

Python參數(shù)代碼

2009-06-23 10:45:18

Hibernate支持

2011-06-10 10:43:12

Ubuntu應(yīng)用安裝

2022-07-07 00:33:34

Java線程同步

2021-11-02 07:54:40

List分片Java

2016-09-09 13:07:56

CentOSJDKLinux

2021-09-10 18:09:42

SQL注入漏洞網(wǎng)絡(luò)攻擊

2009-07-23 15:17:54

JDBC連接Acces

2023-09-25 15:08:43

Python方離群值

2021-10-09 06:59:36

技術(shù)MyBatis數(shù)據(jù)
點贊
收藏

51CTO技術(shù)棧公眾號