Java中List排序的3种方法

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

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

  1. 使用 Comparable 进行排序;

  2. 使用 Comparator 进行排序;

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

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

1.使用 Comparable 排序

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

```java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ListSortExample {
    public static void main(String[] args) {
        // 创建并初始化 List
        List list = new ArrayList() {{
            add(new Person(1, 30, "张三"));
            add(new Person(2, 20, "李四"));
            add(new Person(3, 40, "王五"));
        }};
        // 使用 Comparable 自定的规则进行排序
        Collections.sort(list);
        // 创建ObjectMapper对象
        ObjectMapper objectMapper = new ObjectMapper();

        // 打印 list 集合
        list.forEach(p -> {
            // 将JavaBean对象转换为JSON字符串
            String jsonStr = null;
            try {
                jsonStr = objectMapper.writeValueAsString(p);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            System.out.println(jsonStr);
        });
    }
}


class Person implements Comparable {
    private int id;
    private int age;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name == null ? "" : name;
    }

    public void setName(String name) {
        this.name = 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();
    }
}


```

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

Java中List排序的3种方法

2.使用 Comparator 排序

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

新建 Comparator 比较器;

使用 Comparator 匿名类比较器。

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

2.1 新建 Comparator 比较器

```java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ListSortExample {
    public static void main(String[] args) {
        // 创建并初始化 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());
        // 创建ObjectMapper对象
        ObjectMapper objectMapper = new ObjectMapper();

        // 打印 list 集合
        list.forEach(p -> {
            // 将JavaBean对象转换为JSON字符串
            String jsonStr = null;
            try {
                jsonStr = objectMapper.writeValueAsString(p);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            System.out.println(jsonStr);
        });
    }
}

/**
 * 新建 Person 比较器
 */
class PersonComparator implements Comparator {
    @Override
    public int compare(Person p1, Person p2) {
        return p2.getAge() - p1.getAge();
    }

}

class Person {
    private int id;
    private int age;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name == null ? "" : name;
    }

    public void setName(String name) {
        this.name = name;
    }

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


```

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

Java中List排序的3种方法

2.2 匿名类比较器

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

```java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ListSortExample {
    public static void main(String[] args) {
        // 创建并初始化 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();
            }
        });

        // 创建ObjectMapper对象
        ObjectMapper objectMapper = new ObjectMapper();

        // 打印 list 集合
        list.forEach(p -> {
            // 将JavaBean对象转换为JSON字符串
            String jsonStr = null;
            try {
                jsonStr = objectMapper.writeValueAsString(p);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            System.out.println(jsonStr);
        });
    }
}

class Person {
    private int id;
    private int age;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name == null ? "" : name;
    }

    public void setName(String name) {
        this.name = name;
    }

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


```

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

Java中List排序的3种方法3.使用 Stream 流排序

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

```java
package com.highcom.hc.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class ListSortExample {
    public static void main(String[] args) {
        // 创建并初始化 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());


        // 创建ObjectMapper对象
        ObjectMapper objectMapper = new ObjectMapper();

        // 打印 list 集合
        list.forEach(p -> {
            // 将JavaBean对象转换为JSON字符串
            String jsonStr = null;
            try {
                jsonStr = objectMapper.writeValueAsString(p);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            System.out.println(jsonStr);
        });
    }
}

class Person {
    private int id;
    private int age;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name == null ? "" : name;
    }

    public void setName(String name) {
        this.name = name;
    }

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


```

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

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

Java中List排序的3种方法

扩展:排序字段为 null

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

```java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class ListSortExample {
    public static void main(String[] args) {
        // 创建并初始化 List
        List list = new ArrayList() {{
            add(new Person(1, 30, "张三"));
            add(new Person(2, 20, "李四"));
            add(new Person(3, null, "王五"));
        }};
        // 使用 Stream 排序
        list = list.stream().sorted(Comparator.comparing(Person::getAge).reversed())
                .collect(Collectors.toList());


        // 创建ObjectMapper对象
        ObjectMapper objectMapper = new ObjectMapper();

        // 打印 list 集合
        list.forEach(p -> {
            // 将JavaBean对象转换为JSON字符串
            String jsonStr = null;
            try {
                jsonStr = objectMapper.writeValueAsString(p);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            System.out.println(jsonStr);
        });
    }
}

class Person {
    private int id;
    private Integer  age;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name == null ? "" : name;
    }

    public void setName(String name) {
        this.name = name;
    }

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


```

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

Java中List排序的3种方法想要解决上述问题,需要给 Comparator.comparing 传递第二个参数:Comparator.nullsXXX,如下代码所示:

```java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class ListSortExample {
    public static void main(String[] args) {
        // 创建并初始化 List
        List list = new ArrayList() {{
            add(new Person(1, 30, "张三"));
            add(new Person(2, 20, "李四"));
            add(new Person(3, null, "王五"));
        }};

        // 按照[年龄]排序,但年龄中有一个 null 值
        list = list.stream().sorted(Comparator.comparing(Person::getAge,
                Comparator.nullsFirst(Integer::compareTo)).reversed())
                .collect(Collectors.toList());


        // 创建ObjectMapper对象
        ObjectMapper objectMapper = new ObjectMapper();

        // 打印 list 集合
        list.forEach(p -> {
            // 将JavaBean对象转换为JSON字符串
            String jsonStr = null;
            try {
                jsonStr = objectMapper.writeValueAsString(p);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            System.out.println(jsonStr);
        });
    }
}

class Person {
    private int id;
    private Integer  age;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name == null ? "" : name;
    }

    public void setName(String name) {
        this.name = name;
    }

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


```

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

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

Java中List排序的3种方法

总结

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

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/4933.html

(0)
LomuLomu
上一篇 2024 年 12 月 30 日 下午5:28
下一篇 2024 年 12 月 30 日 下午11:41

相关推荐

  • Java【多线程】(1)进程与线程

    “`markdown 目录 1. 前言 2. 正文 2.1 什么是进程 2.2 PCB(进程控制块) 2.2.1 进程id 2.2.2 内存指针 2.2.3 文件描述符表 2.2.4 进程状态 2.2.4.1 就绪状态 2.2.4.2 阻塞状态 2.2.5 进程优先级 2.2.6 进程上下文 2.2.7 进程的记账信息 2.3 CPU操作进程的方法 2.4…

    2024 年 12 月 28 日
    65400
  • 《深入理解Mybatis原理》MyBatis事务管理机制

    概述 对数据库的事务而言,应该具有以下几点:创建(create)、提交(commit)、回滚(rollback)、关闭(close)。对应地,MyBatis将事务抽象成了Transaction接口: MyBatis的事务管理分为两种形式: 使用JDBC的事务管理机制 :即利用java.sql.Connection对象完成对事务的提交(commit())、回滚…

    2025 年 1 月 14 日
    56300
  • IDEA插件推荐(最新IDEA2024永久激活码,IDEA破解教程)

    IntelliJ IDEA作为JetBrains公司推出的高效集成开发环境(IDE),以其智能化、便捷化的特性深受开发者喜爱。 给大家整理了IDEA永久激活码,IDEA破解教程,需要的直接浏览器访问: docs.qq.com/doc/DWHVFbWVMZklFTllu 然而,使其更加出众的是其丰富的插件生态系统。 插件不仅扩展了IDE的功能,还为开发者提供了…

    未分类 2024 年 7 月 31 日
    2.5K00
  • 【Java多线程】如何使用Java多线程下载网络文件 断点续传

    如何使用Java多线程下载网络文件,并实现断点续传 在现代网络应用中,多线程下载是一种常见的技术,它可以显著提高下载速度并提供更好的用户体验。本篇文章将介绍如何使用Java实现多线程下载,并结合项目中的代码作为示例进行讲解。 1. 多线程下载的基本原理 多线程下载的基本思想是将一个文件分成多个部分,每个部分由一个线程独立下载,最后将这些部分合并成完整的文件。…

    未分类 2025 年 1 月 13 日
    49200
  • JavaCV 图像边缘检测 之 Canny 算法

    # 博主简介 我是**CSDN博客专家**,同时也是**历代文学网**的总架构师,拥有超过**15年**的行业经验。我精通**Java编程**,擅长**高并发系统设计**,对**Springboot和微服务架构**有深入的理解和实践经验。此外,我还熟悉**Linux操作系统**、**ESXI虚拟化技术**,以及**云原生技术栈Docker和Kubernete…

    未分类 2024 年 12 月 27 日
    55000

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信