Java实现List集合的排序:Comparator接口、Collections.sort()方法、stream().sorted()方法的使用

2023-10-31

Java 提供的 List 接口继承了 Collection 接口,因此包含 Collection 中的所有方法。List 是有序集合,允许有相同的元素。ArrayList 是List 接口的一个实现类,它实现了可变大小的数值,允许所有元素,包括 null,并可以根据索引位置对集合进行快速的随机访问。

下面将通过实例来实现使用 Comparator 接口、Collections.sor() 方法、stream().sorted() 方法实现集合的排序。

Comparator 接口、Collections.sor() 方法位于 java.util 包中。

stream().sorted() 方法位于 java.util.stream.Collectors 类下。

 博文系列:

《Java实现List集合的排序:Comparator接口、Collections.sort()方法、stream().sorted()方法的使用》

《Java实现TreeMap集合的排序:Key键的升序与降序、Value值的排序》

(1)创建用户信息实体类

/**
 * 用户信息实体类
 * @author pan_junbiao
 **/
public class UserInfo
{
    private int userId; //用户编号
    private String userName; //用户名称
    private int age; //年龄
    private String blogInfo; //博客信息

    //构造函数
    public UserInfo(int userId, String userName, int age, String blogInfo)
    {
        this.userId = userId;
        this.userName = userName;
        this.age = age;
        this.blogInfo = blogInfo;
    }

    public int getUserId()
    {
        return userId;
    }

    public void setUserId(int userId)
    {
        this.userId = userId;
    }

    public String getUserName()
    {
        return userName;
    }

    public void setUserName(String userName)
    {
        this.userName = userName;
    }

    public int getAge()
    {
        return age;
    }

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

    public String getBlogInfo()
    {
        return blogInfo;
    }

    public void setBlogInfo(String blogInfo)
    {
        this.blogInfo = blogInfo;
    }

    @Override
    public String toString()
    {
        return "用户编号:" + this.userId + " 用户名称:" + this.userName
                +  " 年龄:" + this.age + " 博客信息:" + this.blogInfo;
    }
}

(2)编写获取用户信息列表方法

/**
 * 获取用户信息列表
 * @author pan_junbiao
 */
private List<UserInfo> getUserList()
{
    List<UserInfo> userList = new ArrayList<>();

    //创建用户信息
    UserInfo user1 = new UserInfo(1,"pan_junbiao的博客_01", 18, "您好,欢迎访问 pan_junbiao的博客");
    UserInfo user2 = new UserInfo(2,"pan_junbiao的博客_02", 41, "https://blog.csdn.net/pan_junbiao");
    UserInfo user3 = new UserInfo(3,"pan_junbiao的博客_03", 35, "您好,欢迎访问 pan_junbiao的博客");
    UserInfo user4 = new UserInfo(4,"pan_junbiao的博客_04", 32, "https://blog.csdn.net/pan_junbiao");

    //将用户信息加入Map(故意打乱顺序)
    userList.add(user4);
    userList.add(user2);
    userList.add(user3);
    userList.add(user1);

    return userList;
}

1、Comparator接口

Comparator 接口是一个比较器(比较接口),在 Java 中,可以通过使用 Comparator 接口实现集合或数组的排序。实现 Comparator 接口时,需要重写 int compare(T o1, T o2) 方法,但可以不重新 boolean equals(Object obj) 方法。

(1) int compare(T o1, T o2) 方法:是比较 o1 和 o2 的大小,其中 o1 指的就是第一个要比较的对象, o2 指的是第二个要比的对象。 比较之后会根据大小返回值:

若返回值为负数, 表示 o1 小于 o2小;

若返回值为 0,表示 o1 等于 o2;

若返回值为正数,表示 o1 大于 o2 ;

(2)boolean equals(Object obj) 方法:该方法可以不必重写。然而,在某些情况下,重写此方法可以允许程序确定两个不同的 Comparator 是否强行实施了相同的排序,从而提高性能。

2、Collections.sort()方法

Collections 类提供了两种 sort() 排序方法,分别如下:

(1)sort() 排序方法一:

public static <T extends Comparable<? super T>> void sort(List<T> list) 
{
    list.sort(null);
}

该方法中的泛型 <T> 都是 Comparable 接口的子类,即只有是 Comparable 接口子类类型的对象,才能进行比较排序。如果其他类型的数据要进行比较排序,必须继承 Comparable 接口并重写 int compare(T o1, T o2) 方法和 boolean equals(Object obj) 方法。

(2)sort() 排序方法二:

public static <T> void sort(List<T> list, Comparator<? super T> c) {
    list.sort(c);
}

该方法中指定比较方式 Comparator<? super T> c,即 c 必须实现 Comparator<? super T> 接口,重写 compareTo() 方法指定比较项目。比较项目在类外指定,比较灵活。

【示例】使用 Comparator 比较接口和 Collections.sort() 排序方法实现用户信息的排序。

/**
 * 使用 Comparator 比较接口和 Collections.sort() 排序方法实现用户信息的排序
 * @author pan_junbiao
 */
@Test
public void testUserSort()
{
    //获取用户信息列表
    List<UserInfo> userList = getUserList();

    //排序1:按照用户年龄升序
    Collections.sort(userList, new Comparator<UserInfo>()
    {
        @Override
        public int compare(UserInfo user1, UserInfo user2)
        {
            Integer age1 = user1.getAge();
            Integer age2 = user2.getAge();

            return age1.compareTo(age2);
        }
    });

    System.out.println("按照用户年龄升序:");
    for(UserInfo user : userList)
    {
        System.out.println(user);
    }

    //排序2:按照用户名称倒序
    Collections.sort(userList, new Comparator<UserInfo>()
    {
        @Override
        public int compare(UserInfo user1, UserInfo user2)
        {
            String userName1 = user1.getUserName();
            String userName2 = user2.getUserName();

            return userName2.compareTo(userName1);
        }
    });

    System.out.println("\n按照用户名称倒序:");
    for(UserInfo user : userList)
    {
        System.out.println(user);
    }
}

执行结果:

3、stream().sorted()方法

如果流中的元素的类实现了 Comparable 接口,即有自己的排序规则,那么可以直接调用 sorted() 方法对元素进行排序,如 Stream。反之, 需要调用 sorted((T, T) -> int) 实现 Comparator 接口。

【示例】使用 stream().sorted() 方法实现用户列表根据的排序升序。

/**
 * 使用stream().sorted()方法实现用户列表根据的排序升序
 * @author pan_junbiao
 */
@Test
public void testStreamSorted()
{
    //获取用户信息列表
    List<UserInfo> userList = getUserList();

    //根据年龄排序(升序)
    userList = userList.stream().sorted((u1, u2) -> u1.getAge() - u2.getAge()).collect(Collectors.toList());
    //推荐:userList = userList.stream().sorted(Comparator.comparingInt(User::getAge)).collect(Collectors.toList());
    //降序:userList = userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).collect(Collectors.toList());

    //遍历用户列表
    System.out.println("按照用户年龄升序:");
    userList.forEach(System.out::println);
}

推荐使用如下写法:


//升序
userList = userList.stream().sorted(Comparator.comparingInt(User::getAge)).collect(Collectors.toList());
 
//降序
userList = userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).collect(Collectors.toList());

执行结果:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实现List集合的排序:Comparator接口、Collections.sort()方法、stream().sorted()方法的使用 的相关文章

  • 使用 Java 编辑 jpeg EXIF 数据

    我想编辑 jpg 文件的属性 例如 评论 标题 拍摄日期 相机制造商等 我找到了读取这些数据的库 但我需要一个free带有示例的库edit them 我知道 apache 的成像 sanselan 但我无法用它编辑数据 如果您以前自己使用过
  • 如何重定向到WEB-INF文件夹中的JSP

    我有一个带有 NAV 的 jsp 其中还包含 UL 和以下元素 如下面的代码所示
  • Zuul不转发请求到其他微服务

    我正在使用 Spring Boot 微服务 我已经配置了 eureka zuul 代理和另一个微服务 帐户 如果我直接从帐户拨打电话 则工作正常 帐户和 zuul 服务器都显示在 eureka 上 当我尝试使用 zuul 代理进行访问时 它
  • SpringMVC 和 Hibernate:CannotCreateTransactionException:无法打开 Hibernate 会话进行事务;

    我正在尝试设置并Spring MVC 休眠项目 但它让我发疯 我还会考虑订购 xml 配置文件的建议 我有以下文件 web xml
  • 在 Java 中,三个 true 输入的 XOR 返回 true。为什么?

    下面的代码 System out println 1 0 0 true false false System out println 1 0 1 true false true System out println 1 1 0 true t
  • JaxB2Marshaller 未将 XML 绑定到 Kotlin 数据类

    我正在编写一个批处理作业来解析 XML 提取字段并将它们保存在数据库中 解析 XML 时 它会选取 2 个根元素 但将所有字段保留为空 因此在我的数据库中 我有 2 条记录将为空字段 似乎无法弄清楚为什么它无法读取元素 TIA Bean f
  • Java 中具有级别顺序插入的完整二叉搜索树

    我们接到一个任务 需要编码 二叉搜索树 那个树has to be complete not perfect 这意味着所有不在最低级别或次低级别的节点都应该有 2 个子节点 而最低级别的节点应尽可能远离左侧 我们需要插入到树中等级顺序 所以如
  • Android - 检测电容式触摸屏上的触摸压力?

    我听说过 MotionEvent e float press e getPressure 但这只会在没有触摸时返回 0 当我的手指触摸屏幕时返回 1 是否可以找到手指在触摸电容屏上施加的压力值 或者我的预感是否正确 即这只适用于电阻屏幕 M
  • 在 Spring Security 中创建自定义 PostAuthorize 方法

    我正在尝试创建一个自定义方法 用于预 后授权调用 如下所示 public class CustomLSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandl
  • 如何从网上获取源代码?

    我正在尝试从 Web 获取 HTML 源代码 我尝试这样做 u new URL url URLConnection con u openConnection con setRequestProperty User Agent Mozilla
  • 在Java中打印时差最惯用的方法是什么?

    我熟悉以毫秒为单位的打印时间差 long time System currentTimeMillis do something that takes some time long completedIn System currentTime
  • egit:设置gitignore忽略所有eclipse项目文件

    我在 github 上有一个项目 我想从中删除所有与 eclipse 相关的文件 并允许克隆它的人使用他们想要的任何 ide 这是该项目 https github com vedi0boy Archipelo https github co
  • 调用本机方法时返回 java.lang.UnsatisfiedLinkError

    我正在尝试为第三方 DLL 制作 Java 包装器 我创建了自己的 DLL 充当 JNI 和第三方 DLL 之间的中间人 在java中我加载这个DLL很好但是错误java lang UnsatisfiedLinkError sixense
  • 错误:找不到符号 ArrayList

    我正在尝试创建某种列表来存储数组 表 中的值 我在这里使用数组列表 但我应该使用列表吗 但是 每次我尝试编译时 它都会引发以下错误 找不到标志 符号 ArrayList类 位置 玩家类 TablePlayer 代码如下 public cla
  • Java 堆分析因 SIGABRT 崩溃

    我正在尝试分析由 C 编写的方法分配并插入的本机内存JVM通过JNI 我安装了 valgrind version valgrind 3 13 0 并尝试使用以下选项运行 JVM valgrind tool massif massif out
  • Android 调整图片大小

    我的图像存储在 SD 卡上 每个大小约为 4MB 我想调整每个的大小 而不是将其设置为 ImageView 但我不能使用BitmapFactory decodeFile path 因为异常 java lang OutOfMemoryErro
  • java中的Anagram算法

    我想做字谜算法但是 这段代码不起作用 我的错在哪里 例如 des 和 sed 是字谜 但输出不是字谜 同时我必须使用字符串方法 不是数组 public static boolean isAnagram String s1 String s2
  • java银行程序帐户ID不上去?

    每次创建银行帐户时 帐户 ID 都应增加 1 但每次我尝试提取 Id 时 我只会得到帐户 ID 为 0 任何建议 因为我完全按照我学习的书中的方式进行操作而且它仍然没有更新 帐户构造函数 public class BankAccount p
  • 无法以联觉方式绘制像素、Pi 数

    我想将 pi 数字的每个数字打印为彩色像素 因此 我得到一个带有 pi 数字的输入 然后将其解析为一个列表 每个节点包含一个数字 我知道 稍后我将使用一个数组 但我从来没有把它画到屏幕上 有人能帮我看看我错在哪里吗 import java
  • Java中不同格式的字符串解析为日期

    我想转换String to Date以不同的格式 例如 我从用户那里得到 String fromDate 19 05 2009 i e dd MM yyyy format 我想转换这个fromDate作为日期对象 yyyy MM dd fo

随机推荐