• Comparator 和 Comparable比较


    Comparable是排序接口: 若一个类实现了Comparable接口,就意味着“该类支持排序”。

    Comparator是比较器: 我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。

    我们需要创建一个包含了用户列表的 List 集合,并按用户的年龄从大到小进行排序,具体实现代码如下: 第一种:实现Comparable<>接口

     写一个Person类:

    1. class Person implements Comparable<Person>{
    2. Integer id;
    3. String name;
    4. Integer age;
    5. public Integer getId() {
    6. return id;
    7. }
    8. public void setId(Integer id) {
    9. this.id = id;
    10. }
    11. public String getName() {
    12. return name;
    13. }
    14. public void setName(String name) {
    15. this.name = name;
    16. }
    17. public Integer getAge() {
    18. return age;
    19. }
    20. public void setAge(Integer age) {
    21. this.age = age;
    22. }
    23. @Override
    24. public String toString() {
    25. return "Person{" +
    26. "id=" + id +
    27. ", name='" + name + '\'' +
    28. ", age=" + age +
    29. '}';
    30. }
    31. @Override
    32. public int compareTo(Person o) {
    33. //按照年龄从大到小排序
    34. return o.getAge()-this.getAge();
    35. }
    36. }

    实现结果测试:

    1. public static void main(String[] args){
    2. //假设放进去三个对象,直接调用
    3. List<Person> pr=new ArrayList<Person>(){{
    4. add(new Person(1,"huitao1",32));
    5. add(new Person(2,"huitao2",40));
    6. add(new Person(3,"huitao3",28));
    7. }};
    8. //很重要
    9. Collections.sort(pr);
    10. pr.forEach(p->{
    11. System.out.print(p);
    12. });
    13. }

    结果按照40、32、28进行了排序 

     第二种: Comparator 排序

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

    • 新建 Comparator 比较器;
    • 使用 Comparator 匿名类比较器。

     

    1. static class Person {
    2. Integer id;
    3. String name;
    4. Integer age;
    5. public Person(Integer id, String name, Integer age) {
    6. this.id = id;
    7. this.name = name;
    8. this.age = age;
    9. }
    10. public Integer getId() {
    11. return id;
    12. }
    13. public void setId(Integer id) {
    14. this.id = id;
    15. }
    16. public String getName() {
    17. return name;
    18. }
    19. public void setName(String name) {
    20. this.name = name;
    21. }
    22. public Integer getAge() {
    23. return age;
    24. }
    25. public void setAge(Integer age) {
    26. this.age = age;
    27. }
    28. @Override
    29. public String toString() {
    30. return "Person{" +
    31. "id=" + id +
    32. ", name='" + name + '\'' +
    33. ", age=" + age +
    34. '}';
    35. }
    36. }

    编写一个比较器类: 

    1. static class ToPerson implements Comparator<Person>{
    2. @Override
    3. public int compare(Person o1, Person o2) {
    4. return o1.getAge() - o2.getAge();
    5. }
    6. }
    1. public static void main(String[] args){
    2. List<Person> pr=new ArrayList<Person>(){{
    3. add(new Person(1,"huitao1",32));
    4. add(new Person(2,"huitao2",40));
    5. add(new Person(3,"huitao3",28));
    6. }};
    7. //很重要
    8. Collections.sort(pr,new ToPerson());
    9. pr.forEach(p->{
    10. System.out.print(p);
    11. });
    12. }

    测试结果:

    分别为28、32、40,如果要从大到小,可以编写为

    static class ToPerson implements Comparator{
    
        @Override
        public int compare(Person o1, Person o2) {
            return o2.getAge() - o1.getAge();
        }
    }

    以匿名类的方式访问:

    1. static class Person {
    2. Integer id;
    3. String name;
    4. Integer age;
    5. public Person(Integer id, String name, Integer age) {
    6. this.id = id;
    7. this.name = name;
    8. this.age = age;
    9. }
    10. public Integer getId() {
    11. return id;
    12. }
    13. public void setId(Integer id) {
    14. this.id = id;
    15. }
    16. public String getName() {
    17. return name;
    18. }
    19. public void setName(String name) {
    20. this.name = name;
    21. }
    22. public Integer getAge() {
    23. return age;
    24. }
    25. public void setAge(Integer age) {
    26. this.age = age;
    27. }
    28. @Override
    29. public String toString() {
    30. return "Person{" +
    31. "id=" + id +
    32. ", name='" + name + '\'' +
    33. ", age=" + age +
    34. '}';
    35. }
    36. }
    1. public static void main(String[] args){
    2. List<Person> pr=new ArrayList<Person>(){{
    3. add(new Person(1,"huitao1",32));
    4. add(new Person(2,"huitao2",40));
    5. add(new Person(3,"huitao3",28));
    6. }};
    7. //很重要
    8. Collections.sort(pr, new Comparator<Person>() {
    9. @Override
    10. public int compare(Person o1, Person o2) {
    11. return o2.getAge() - o1.getAge();
    12. }
    13. });
    14. pr.forEach(p->{
    15. System.out.print(p);
    16. });
    17. }

    第三种:使用 Stream 流排序 

    1. public static void main(String[] args){
    2. List<Person> pr=new ArrayList<Person>(){{
    3. add(new Person(1,"huitao1",32));
    4. add(new Person(2,"huitao2",40));
    5. add(new Person(3,"huitao3",28));
    6. }};
    7. pr= pr.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList());
    8. pr.forEach(p->{
    9. System.out.print(p);
    10. });
    11. }
    12. static class Person {
    13. Integer id;
    14. String name;
    15. Integer age;
    16. public Person(Integer id, String name, Integer age) {
    17. this.id = id;
    18. this.name = name;
    19. this.age = age;
    20. }
    21. public Integer getId() {
    22. return id;
    23. }
    24. public void setId(Integer id) {
    25. this.id = id;
    26. }
    27. public String getName() {
    28. return name;
    29. }
    30. public void setName(String name) {
    31. this.name = name;
    32. }
    33. public Integer getAge() {
    34. return age;
    35. }
    36. public void setAge(Integer age) {
    37. this.age = age;
    38. }
    39. @Override
    40. public String toString() {
    41. return "Person{" +
    42. "id=" + id +
    43. ", name='" + name + '\'' +
    44. ", age=" + age +
    45. '}';
    46. }
    47. }

     

     stream()如果排序属性出现null,报告空指针个错误,解决办法

    1. public static void main(String[] args){
    2. List<Person> pr=new ArrayList<Person>(){{
    3. add(new Person(1,"huitao1",32));
    4. add(new Person(2,"huitao2",40));
    5. add(new Person(3,"huitao3",28));
    6. add(new Person(4,"huitao3",null));
    7. }};
    8. pr= pr.stream().sorted(Comparator.comparing(Person::getAge,Comparator.nullsFirst(Integer::compareTo)).reversed()).collect(Collectors.toList());
    9. pr.forEach(p->{
    10. System.out.print(p);
    11. });
    12. }
    13. static class Person {
    14. Integer id;
    15. String name;
    16. Integer age;
    17. public Person(Integer id, String name, Integer age) {
    18. this.id = id;
    19. this.name = name;
    20. this.age = age;
    21. }
    22. public Integer getId() {
    23. return id;
    24. }
    25. public void setId(Integer id) {
    26. this.id = id;
    27. }
    28. public String getName() {
    29. return name;
    30. }
    31. public void setName(String name) {
    32. this.name = name;
    33. }
    34. public Integer getAge() {
    35. return age;
    36. }
    37. public void setAge(Integer age) {
    38. this.age = age;
    39. }
    40. @Override
    41. public String toString() {
    42. return "Person{" +
    43. "id=" + id +
    44. ", name='" + name + '\'' +
    45. ", age=" + age +
    46. '}';
    47. }
    48. }

     

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

  • 相关阅读:
    浏览量5.54亿,“平替大军”击退“钱包刺客”?丨小红书消费趋势分析
    数据结构与算法:树 顺序存储二叉树(二)
    flutter 版本更新
    【C语言】程序环境深度剖析
    【python-AI篇】人工智能技能树思维导图
    《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(2)-初识Fiddler让你理性认识一下
    2022年,有哪些适合普通人的风口项目?
    [附源码]Python计算机毕业设计高校辅导员工作管理系统
    Vue3学习系列之《列表渲染》
    测试人员学Java入门指南
  • 原文地址:https://blog.csdn.net/chehec2010/article/details/133362757