当前位置:   article > 正文

Java中List排序的3种方法_java list排序

java list排序

在我们程序的编写中,有时候我们需要在 Java 程序中对 List 集合进行排序操作。比如获取所有用户的列表,但列表默认是以用户编号从小到大进行排序的,而我们的系统需要按照用户的年龄从大到小进行排序,这个时候,我们就需要对 List 集合进行自定义排序操作了。

List 排序的常见方法有以下 3 种:

  1. 使用 Comparable 进行排序;

  2. 使用 Comparator 进行排序;

  3. 如果是 JDK 8 以上的环境,也可以使用 Stream 流进行排序。

下面我们分别来看各种排序方法的具体实现。

1.使用 Comparable 排序

创建一个包含了用户列表的 List 集合,并按用户的年龄从大到小进行排序,具体实现代码如下:

  1. import com.fasterxml.jackson.core.JsonProcessingException;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.List;
  6. public class ListSortExample {
  7. public static void main(String[] args) {
  8. // 创建并初始化 List
  9. List<Person> list = new ArrayList<Person>() {{
  10. add(new Person(1, 30, "张三"));
  11. add(new Person(2, 20, "李四"));
  12. add(new Person(3, 40, "王五"));
  13. }};
  14. // 使用 Comparable 自定的规则进行排序
  15. Collections.sort(list);
  16. // 创建ObjectMapper对象
  17. ObjectMapper objectMapper = new ObjectMapper();
  18. // 打印 list 集合
  19. list.forEach(p -> {
  20. // 将JavaBean对象转换为JSON字符串
  21. String jsonStr = null;
  22. try {
  23. jsonStr = objectMapper.writeValueAsString(p);
  24. } catch (JsonProcessingException e) {
  25. e.printStackTrace();
  26. }
  27. System.out.println(jsonStr);
  28. });
  29. }
  30. }
  31. class Person implements Comparable<Person> {
  32. private int id;
  33. private int age;
  34. private String name;
  35. public int getId() {
  36. return id;
  37. }
  38. public void setId(int id) {
  39. this.id = id;
  40. }
  41. public int getAge() {
  42. return age;
  43. }
  44. public void setAge(int age) {
  45. this.age = age;
  46. }
  47. public String getName() {
  48. return name == null ? "" : name;
  49. }
  50. public void setName(String name) {
  51. this.name = name;
  52. }
  53. public Person(int id, int age, String name) {
  54. this.id = id;
  55. this.age = age;
  56. this.name = name;
  57. }
  58. @Override
  59. public int compareTo(Person p) {
  60. return p.getAge() - this.getAge();
  61. }
  62. }

以上代码的执行结果,如下图所示:

2.使用 Comparator 排序

Comparable 是类内部的比较方法,而 Comparator 是排序类外部的比较器。使用 Comparator 比较器,无需修改原 Person 类,只需要扩充一个 Person 类的比较器就行了,Comparator 的实现方法有以下两种:

新建 Comparator 比较器;

使用 Comparator 匿名类比较器。

其中,第二种实现方法要更简洁一些,我们通过下面的具体代码,来观察一下二者的区别。


2.1 新建 Comparator 比较器
  1. import com.fasterxml.jackson.core.JsonProcessingException;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.Comparator;
  6. import java.util.List;
  7. public class ListSortExample {
  8. public static void main(String[] args) {
  9. // 创建并初始化 List
  10. List<Person> list = new ArrayList<Person>() {{
  11. add(new Person(1, 30, "张三"));
  12. add(new Person(2, 20, "李四"));
  13. add(new Person(3, 40, "王五"));
  14. }};
  15. // 使用 Comparator 比较器排序
  16. Collections.sort(list, new PersonComparator());
  17. // 创建ObjectMapper对象
  18. ObjectMapper objectMapper = new ObjectMapper();
  19. // 打印 list 集合
  20. list.forEach(p -> {
  21. // 将JavaBean对象转换为JSON字符串
  22. String jsonStr = null;
  23. try {
  24. jsonStr = objectMapper.writeValueAsString(p);
  25. } catch (JsonProcessingException e) {
  26. e.printStackTrace();
  27. }
  28. System.out.println(jsonStr);
  29. });
  30. }
  31. }
  32. /**
  33. * 新建 Person 比较器
  34. */
  35. class PersonComparator implements Comparator<Person> {
  36. @Override
  37. public int compare(Person p1, Person p2) {
  38. return p2.getAge() - p1.getAge();
  39. }
  40. }
  41. class Person {
  42. private int id;
  43. private int age;
  44. private String name;
  45. public int getId() {
  46. return id;
  47. }
  48. public void setId(int id) {
  49. this.id = id;
  50. }
  51. public int getAge() {
  52. return age;
  53. }
  54. public void setAge(int age) {
  55. this.age = age;
  56. }
  57. public String getName() {
  58. return name == null ? "" : name;
  59. }
  60. public void setName(String name) {
  61. this.name = name;
  62. }
  63. public Person(int id, int age, String name) {
  64. this.id = id;
  65. this.age = age;
  66. this.name = name;
  67. }
  68. }

以上代码的执行结果,如下图所示:

2.2 匿名类比较器

比较器 Comparator 可以使用更简洁的匿名类的方式,来实现排序功能,具体实现代码如下:

  1. import com.fasterxml.jackson.core.JsonProcessingException;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.Comparator;
  6. import java.util.List;
  7. public class ListSortExample {
  8. public static void main(String[] args) {
  9. // 创建并初始化 List
  10. List<Person> list = new ArrayList<Person>() {{
  11. add(new Person(1, 30, "张三"));
  12. add(new Person(2, 20, "李四"));
  13. add(new Person(3, 40, "王五"));
  14. }};
  15. // 使用匿名比较器排序
  16. Collections.sort(list, new Comparator<Person>() {
  17. @Override
  18. public int compare(Person p1, Person p2) {
  19. return p2.getAge() - p1.getAge();
  20. }
  21. });
  22. // 创建ObjectMapper对象
  23. ObjectMapper objectMapper = new ObjectMapper();
  24. // 打印 list 集合
  25. list.forEach(p -> {
  26. // 将JavaBean对象转换为JSON字符串
  27. String jsonStr = null;
  28. try {
  29. jsonStr = objectMapper.writeValueAsString(p);
  30. } catch (JsonProcessingException e) {
  31. e.printStackTrace();
  32. }
  33. System.out.println(jsonStr);
  34. });
  35. }
  36. }
  37. class Person {
  38. private int id;
  39. private int age;
  40. private String name;
  41. public int getId() {
  42. return id;
  43. }
  44. public void setId(int id) {
  45. this.id = id;
  46. }
  47. public int getAge() {
  48. return age;
  49. }
  50. public void setAge(int age) {
  51. this.age = age;
  52. }
  53. public String getName() {
  54. return name == null ? "" : name;
  55. }
  56. public void setName(String name) {
  57. this.name = name;
  58. }
  59. public Person(int id, int age, String name) {
  60. this.id = id;
  61. this.age = age;
  62. this.name = name;
  63. }
  64. }

以上代码的执行结果,如下图所示:

3.使用 Stream 流排序

在 JDK 8 之后可以使用更加简单的方法 Stream 流来实现排序功能,它的实现只需要一行代码,具体实现如下:

  1. package com.highcom.hc.api;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import java.util.ArrayList;
  5. import java.util.Collections;
  6. import java.util.Comparator;
  7. import java.util.List;
  8. import java.util.stream.Collectors;
  9. public class ListSortExample {
  10. public static void main(String[] args) {
  11. // 创建并初始化 List
  12. List<Person> list = new ArrayList<Person>() {{
  13. add(new Person(1, 30, "张三"));
  14. add(new Person(2, 20, "李四"));
  15. add(new Person(3, 40, "王五"));
  16. }};
  17. // 使用 Stream 排序
  18. list = list.stream().sorted(Comparator.comparing(Person::getAge).reversed())
  19. .collect(Collectors.toList());
  20. // 创建ObjectMapper对象
  21. ObjectMapper objectMapper = new ObjectMapper();
  22. // 打印 list 集合
  23. list.forEach(p -> {
  24. // 将JavaBean对象转换为JSON字符串
  25. String jsonStr = null;
  26. try {
  27. jsonStr = objectMapper.writeValueAsString(p);
  28. } catch (JsonProcessingException e) {
  29. e.printStackTrace();
  30. }
  31. System.out.println(jsonStr);
  32. });
  33. }
  34. }
  35. class Person {
  36. private int id;
  37. private int age;
  38. private String name;
  39. public int getId() {
  40. return id;
  41. }
  42. public void setId(int id) {
  43. this.id = id;
  44. }
  45. public int getAge() {
  46. return age;
  47. }
  48. public void setAge(int age) {
  49. this.age = age;
  50. }
  51. public String getName() {
  52. return name == null ? "" : name;
  53. }
  54. public void setName(String name) {
  55. this.name = name;
  56. }
  57. public Person(int id, int age, String name) {
  58. this.id = id;
  59. this.age = age;
  60. this.name = name;
  61. }
  62. }

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

以上代码的执行结果,如下图所示:

扩展:排序字段为 null

使用 Stream 进行排序时,如果排序的字段出现 null 值就会导致异常发生,具体示例如下:

  1. import com.fasterxml.jackson.core.JsonProcessingException;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.Comparator;
  6. import java.util.List;
  7. import java.util.stream.Collectors;
  8. public class ListSortExample {
  9. public static void main(String[] args) {
  10. // 创建并初始化 List
  11. List<Person> list = new ArrayList<Person>() {{
  12. add(new Person(1, 30, "张三"));
  13. add(new Person(2, 20, "李四"));
  14. add(new Person(3, null, "王五"));
  15. }};
  16. // 使用 Stream 排序
  17. list = list.stream().sorted(Comparator.comparing(Person::getAge).reversed())
  18. .collect(Collectors.toList());
  19. // 创建ObjectMapper对象
  20. ObjectMapper objectMapper = new ObjectMapper();
  21. // 打印 list 集合
  22. list.forEach(p -> {
  23. // 将JavaBean对象转换为JSON字符串
  24. String jsonStr = null;
  25. try {
  26. jsonStr = objectMapper.writeValueAsString(p);
  27. } catch (JsonProcessingException e) {
  28. e.printStackTrace();
  29. }
  30. System.out.println(jsonStr);
  31. });
  32. }
  33. }
  34. class Person {
  35. private int id;
  36. private Integer age;
  37. private String name;
  38. public int getId() {
  39. return id;
  40. }
  41. public void setId(int id) {
  42. this.id = id;
  43. }
  44. public int getAge() {
  45. return age;
  46. }
  47. public void setAge(int age) {
  48. this.age = age;
  49. }
  50. public String getName() {
  51. return name == null ? "" : name;
  52. }
  53. public void setName(String name) {
  54. this.name = name;
  55. }
  56. public Person(int id, Integer age, String name) {
  57. this.id = id;
  58. this.age = age;
  59. this.name = name;
  60. }
  61. }

以上代码的执行结果,如下图所示:

想要解决上述问题,需要给 Comparator.comparing 传递第二个参数:Comparator.nullsXXX,如下代码所示:

  1. import com.fasterxml.jackson.core.JsonProcessingException;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.Comparator;
  6. import java.util.List;
  7. import java.util.stream.Collectors;
  8. public class ListSortExample {
  9. public static void main(String[] args) {
  10. // 创建并初始化 List
  11. List<Person> list = new ArrayList<Person>() {{
  12. add(new Person(1, 30, "张三"));
  13. add(new Person(2, 20, "李四"));
  14. add(new Person(3, null, "王五"));
  15. }};
  16. // 按照[年龄]排序,但年龄中有一个 null 值
  17. list = list.stream().sorted(Comparator.comparing(Person::getAge,
  18. Comparator.nullsFirst(Integer::compareTo)).reversed())
  19. .collect(Collectors.toList());
  20. // 创建ObjectMapper对象
  21. ObjectMapper objectMapper = new ObjectMapper();
  22. // 打印 list 集合
  23. list.forEach(p -> {
  24. // 将JavaBean对象转换为JSON字符串
  25. String jsonStr = null;
  26. try {
  27. jsonStr = objectMapper.writeValueAsString(p);
  28. } catch (JsonProcessingException e) {
  29. e.printStackTrace();
  30. }
  31. System.out.println(jsonStr);
  32. });
  33. }
  34. }
  35. class Person {
  36. private int id;
  37. private Integer age;
  38. private String name;
  39. public int getId() {
  40. return id;
  41. }
  42. public void setId(int id) {
  43. this.id = id;
  44. }
  45. public Integer getAge() {
  46. return age;
  47. }
  48. public void setAge(Integer age) {
  49. this.age = age;
  50. }
  51. public String getName() {
  52. return name == null ? "" : name;
  53. }
  54. public void setName(String name) {
  55. this.name = name;
  56. }
  57. public Person(int id, Integer age, String name) {
  58. this.id = id;
  59. this.age = age;
  60. this.name = name;
  61. }
  62. }

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

以上代码的执行结果,如下图所示:

总结

本文介绍了 3 种 List 排序的方法,前两种方法常用于 JDK 8 之前的版本,其中比较器 Comparator 有两种实现的写法,而在 JDK 8 之后的版本,就可以使用 Comparator.comparing 实现排序了,如果排序字段中可能出现 null 值,要使用 Comparator.nullsXXX 进行排序处理(否则会报错)
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/784138
推荐阅读
相关标签
  

闽ICP备14008679号