当前位置: 首页 > article >正文

List排序的方法

List 排序方法:

1.  list 的 sort()

package com.example.a;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
class User{
    private Integer score;
    private Integer age;
    public User(Integer score, Integer age){
        super();
        this.score = score;
        this.age = age;
    }
    public Integer getScore() {
        return score;
    }
    public void setScore(Integer score) {
        this.score = score;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}
public class Demo {
    public static void main(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User(95, 26));
        users.add(new User(84, 23));
        users.add(new User(96, 25));
        users.add(new User(95, 24));
        // 单字段排序
        users.sort(Comparator.comparing(User::getAge));
        for(User user : users){
            System.out.println(user.getScore() + "," + user.getAge());
        }

        System.out.println("---------------------------------");
        // 多字段排序(法1)
        users.sort((o1, o2) -> {
            // 这里必须要在中间加分隔符。否则,若都是数字,会变成数字相加,再转为字符串
            String tmp1 = o1.getScore() + ":" + o1.getAge();
            String tmp2 = o2.getScore() + ":" + o2.getAge();
            return tmp1.compareTo(tmp2);
        });
        for(User user : users){
            System.out.println(user.getScore() + ":" + user.getAge());
        }

        System.out.println("---------------------------------");
        // 多字段排序(法2)
        users.sort((o1, o2) -> {
            int i = o2.getScore() - o1.getScore();
            if (i == 0) {
                return o1.getAge() - o2.getAge();
            }
            return i;
        });
        for(User user : users){
            System.out.println(user.getScore() + "," + user.getAge());
        }
    }
}

输出结果:

84,23
95,24
96,25
95,26
---------------------------------
84:23
95:24
95:26
96:25
---------------------------------
96,25
95,24
95,26
84,23

单字段排序:

        在代码中,定义了 User 类包含 score 和 age 属性,创建了 ArrayList<User> 并添加了多个 User 对象实例。使用 users.sort(Comparator.comparing(User::getAge)); 语句按照 age字段对 users 列表进行排序。这里利用了 Comparator.comparing() 方法,它接收一个获取属性的函数式接口引用(此处为 User::getAge,表示按照 User 对象的 age 属性进行比较),然后sort 方法会依据这个比较逻辑对列表元素进行排序。排序后通过循环打印出每个用户的 score 和 age,结果展示了按照年龄从小到大排序后的用户信息。

多字段排序示例(法1):

        使用自定义的比较逻辑,通过 lambda 表达式实现。在 lambda 表达式中,先将 User 对象的 score 和 age 组合成一个字符串(中间用:分隔,是为了避免数字直接相加等问题,保证按预期拼接字符串用于比较),如 String tmp1 = o1.getScore() + ":" + o1.getAge();,然后通过比较两个这样组合后的字符串大小(return tmp1.compareTo(tmp2);)来确定元素的顺序,实现了多字段排序效果。

多字段排序示例(法2):

        同样是用 lambda 表达式实现多字段排序。先比较 score 字段(int i = o2.getScore() - o1.getScore();,通过差值判断大小,若差值为 0 则表示 score 相同),当 score 相同时,再比较 age 字段(return o1.getAge() - o2.getAge();),最终返回比较结果来确定元素顺序,按照成绩降序、年龄升序(成绩相同时)的规则对列表进行了排序。

2. JDK8 的 stream 方法

2.1 对简单整数列表进行排序

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

public class StreamSortExample {
    public static void main(String[] args) {
        // 创建一个包含整数的ArrayList
        List<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(2);
        numbers.add(8);
        numbers.add(1);

        // 使用Stream的sorted方法进行排序,并通过collect方法将结果收集回List
        List<Integer> sortedNumbers = numbers.stream()
               .sorted()
               .collect(Collectors.toList());

        System.out.println("排序后的整数列表: " + sortedNumbers);
    }
}

在上述代码中:

        2.1.1. 首先创建了一个ArrayList,其中包含了几个整数元素;

        2.1.2. 接着调用stream()方法将List转换为Stream流,这样就能使用流相关的操作了;

        2.1.3. 然后使用sorted()方法,对于像Integer这种基本数据类型对应的包装类(因为Stream操作的是对象),它默认会按照自然顺序(在这里就是数字从小到大的顺序)对元素进行排序;

        2.1.4. 最后使用collect(Collectors.toList())将排序后的流元素收集回一个新的List,并将其打印出来,运行结果会显示按照从小到大顺序排好的整数列表;

2.2 对自定义对象列表按照单个属性排序

class Student {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class StreamSortExample {
    public static void main(String[] args) {
        // 创建一个包含Student对象的ArrayList
        List<Student> students = new ArrayList<>();
        students.add(new Student("Alice", 20));
        students.add(new Student("Bob", 18));
        students.add(new Student("Charlie", 22));

        // 使用Stream的sorted方法结合Comparator按照年龄对学生列表进行排序
        List<Student> sortedStudents = students.stream()
               .sorted(Comparator.comparing(Student::getAge))
               .collect(Collectors.toList());

        // 打印排序后的学生列表信息
        sortedStudents.forEach(student -> System.out.println("姓名: " + student.getName() + ", 年龄: " + student.getAge()));
    }
}

在上述代码中:

        2.2.1. 先定义了Student类,包含nameage两个属性;

        2.2.2. 创建了ArrayList<Student>并添加了几个Student实例;

        2.2.3. 在使用Stream进行排序时,调用sorted方法并传入一个Comparator,这里通过Comparator.comparing(Student::getAge)来指定按照Student对象的age属性进行比较排序,也就是会按照年龄从小到大对学生列表进行排序;

        2.1.4. 最后使用collect(Collectors.toList())收集排序后的元素为新的列表,并且通过forEach方法遍历打印出每个学生的姓名和年龄信息,展示排序后的结果;

2.3 对自定义对象列表按照多个属性排序

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

public class StreamSortExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Alice", 20));
        students.add(new Student("Bob", 18));
        students.add(new Student("Charlie", 20));

        // 使用Stream的sorted方法结合Comparator按照年龄和姓名对学生列表进行排序
        List<Student> sortedStudents = students.stream()
               .sorted(Comparator.comparing(Student::getAge)
                       .thenComparing(Student::getName))
               .collect(Collectors.toList());

        sortedStudents.forEach(student -> System.out.println("姓名: " + student.getName() + ", 年龄: " + student.getAge()));
    }
}

在上述代码中:

        2.3.1. 创建了包含Student对象的列表,其中有年龄相同的情况;

        2.3.2. 调用sorted方法时,传入的Comparator通过链式调用thenComparing来添加额外的比较条件。首先通过Comparator.comparing(Student::getAge)按照年龄进行比较排序,然后使用.thenComparing(Student::getName)表示在年龄相同的情况下,再按照姓名的字典顺序进行排序;

        2.3.3. 最后同样收集排序后的元素为新列表并遍历打印出信息,展示按照多属性排序后的结果;

法3:Comparator 的 compare() 

package org.example.a;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class User{
    private int score;
    private int age;
    public User(int score, int age){
        super();
        this.score = score;
        this.age = age;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
public class Demo {
    public static void main(String[] args) {
        List<User> users = new ArrayList<User>();
        users.add(new User(95, 26));
        users.add(new User(84, 23));
        users.add(new User(96, 25));
        users.add(new User(95, 24));
        Collections.sort(users, new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                int i = o2.getScore() - o1.getScore();
                if(i == 0){
                    return o1.getAge() - o2.getAge();
                }
                return i;
            }
        });
        for(User user : users){
            System.out.println(user.getScore() + "," + user.getAge());
        }
    }
}

输出结果:

96,25
95,24
95,26
84,23

        在上述代码中,ArrayList<User> 并添加了多个User对象实例,然后使用Collections.sort(users, new Comparator<User>() {... });来进行排序。这里Collections.sort()方法接收要排序的列表以及一个 Comparator 接口的实现类实例(此处通过匿名内部类的方式实现)。在 compare 方法中,先比较 score 字段(通过差值判断大小,差值为 0 表示成绩相同),若成绩相同则比较age字段,最后返回比较结果,按照成绩降序、年龄升序(成绩相同时)的规则对列表进行了排序,循环打印出排序后的用户信息展示了排序效果。

法4:Comparable 的 compareTo()

4.1 默认按增序排序:

package org.example.a;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Demo {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<Integer>();
        nums.add(3);
        nums.add(5);
        nums.add(1);
        nums.add(0);
        System.out.println(nums);
        Collections.sort(nums);
        System.out.println(nums);
    }
}

输出结果:

[3, 5, 1, 0]
[0, 1, 3, 5]

        对于简单的 ArrayList<Integer>,创建列表并添加元素后,直接调用Collections.sort(nums);,由于Integer类实现了 Comparable 接口,其内部的 compareTo 方法定义了默认的按照数字大小的增序排序逻辑,所以列表会按照从小到大的顺序被排序,从打印结果[3, 5, 1, 0][0, 1, 3, 5]可以看出排序前后的变化。

4.2 自定义对象排序示例:

package org.example.a;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class User implements Comparable<User>{
    private int score;
    private int age;
    public User(int score, int age){
        super();
        this.score = score;
        this.age = age;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public int compareTo(User o) {
        int i = o.getScore() - this.getScore();
        if(i == 0){
            return this.getAge() - o.getAge();
        }
        return i;
    }
}
public class Demo {
    public static void main(String[] args) {
        List<User> users = new ArrayList<User>();
        users.add(new User(95, 26));
        users.add(new User(84, 23));
        users.add(new User(96, 25));
        users.add(new User(95, 24));
        Collections.sort(users);
        for(User user : users){
            System.out.println(user.getScore() + "," + user.getAge());
        }
    }
}

输出结果:

96,25
95,24
95,26
84,23

        定义的 User 类实现了 Comparable<User> 接口,重写了 compareTo 方法。在 compareTo方法中,先比较 score 字段(通过差值判断,不过这里是用 o.getScore() - this.getScore();实现降序效果,差值为 0 表示成绩相同),若成绩相同则比较 age 字段(按照升序比较,return this.getAge() - o.getAge();),最后返回比较结果。通过 Collections.sort(users);ArrayList<User> 进行排序,循环打印结果展示了按照成绩降序、年龄升序(成绩相同时)的规则排序后的用户信息。


http://www.kler.cn/a/460372.html

相关文章:

  • JavaWeb开发(五)Servlet-ServletContext
  • Redis 发布订阅(Pub/Sub)机制详解
  • MLP、CNN、Transformer 的区别解析
  • Spring Boot 3 构建统一的请求响应参数、异常处理、以及统一的异常状态码
  • C# 设计模式(创建型模式):单例模式
  • 前端编码技巧与规范
  • JVM和异常
  • 【华为OD-E卷 - 机房布局 100分(python、java、c++、js、c)】
  • Edge如何获得纯净的启动界面
  • XIAO Esp32 S3 轻松发送 HTTP 请求,打造智能物联网应用
  • 优化咨询行业团队协作:通过有效的项目管理工具实现高效协作
  • 爬虫代码中如何添加异常处理?
  • torch.nn.Linear(p_input, p_output,bias)
  • 2024Jinger的前端学习内容总结——前端学习路线(超全)
  • 使用 Python 和 LabelMe 实现图片验证码的自动标注
  • 【ArcGISPro/GeoScenePro】检查多光谱影像的属性并优化其外观
  • Spring Boot 3 文件上传、多文件上传、大文件分片上传、文件流处理以及批量操作
  • WPF系列五:图形控件Ellipse
  • log4j2的Strategy、log4j2的DefaultRolloverStrategy、删除过期文件
  • 自己编写甘特图的绘制程序
  • golang 熔断限流降级
  • 商汤C++开发面试题及参考答案
  • 【postgresql 物化视图】自动刷新物化视图2种方法
  • order by语句执行顺序
  • Vue2/Vue3使用DataV
  • .net core 的数据库编程