List对象进行排序

目录

一、List对象中某个值进行排序

代码示例

注意事项

[二、List.sort 和 Collections.sort 异同](#二、List.sort 和 Collections.sort 异同)

[1. 方法所属](#1. 方法所属)

[2. 使用方式](#2. 使用方式)

[3. 是否修改原列表](#3. 是否修改原列表)

[4. 泛型支持](#4. 泛型支持)

[5. 性能](#5. 性能)

[6. 适用场景](#6. 适用场景)

[7. 示例代码对比](#7. 示例代码对比)

[使用 testList.sort](#使用 testList.sort)

[使用 Collections.sort](#使用 Collections.sort)

[8. 总结](#8. 总结)

三、为对象多个属性进行排序

示例代码


一、List对象中某个值进行排序

用空间换时间,Java在内存中进行对象集合排序。

在 Java 中,可以使用 Listsort 方法或者 Collections.sort 方法,结合自定义的比较器(Comparator),对 List<Test> 按照 LocalDate 类型的字段 startTime 进行排序。

代码示例

java 复制代码
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Test {
    private String name;
    private LocalDate startTime;

    // 构造函数
    public Test(String name, LocalDate startTime) {
        this.name = name;
        this.startTime = startTime;
    }

    // Getter 和 Setter
    public LocalDate getStartTime() {
        return startTime;
    }

    @Override
    public String toString() {
        return "Test{name='" + name + "', startTime=" + startTime + "}";
    }
}

public class SortExample {
    public static void main(String[] args) {
        // 创建一个 Test 对象列表
        List<Test> testList = new ArrayList<>();
        testList.add(new Test("Test1", LocalDate.of(2023, 3, 15)));
        testList.add(new Test("Test2", LocalDate.of(2023, 1, 10)));
        testList.add(new Test("Test3", LocalDate.of(2023, 2, 20)));

        // 使用 Comparator 对 startTime 字段进行排序
        testList.sort(Comparator.comparing(Test::getStartTime));

        // 或者使用 Collections.sort 方法
        // Collections.sort(testList, Comparator.comparing(Test::getStartTime));

        // 输出排序后的结果
        testList.forEach(System.out::println);
    }
}

如果需要按降序排序,可以在 Comparator 上调用 reversed() 方法:

java 复制代码
testList.sort(Comparator.comparing(Test::getStartTime).reversed());

注意事项

  1. 空值 处理

    java 复制代码
    testList.sort(Comparator.comparing(Test::getStartTime, Comparator.nullsLast(Comparator.naturalOrder())));
  2. 线程安全List.sort 方法会直接修改原列表的内容。如果需要保留原始列表不变,可以先复制一份再排序。

  3. Java 版本: 以上代码适用于 Java 8 及更高版本,因为 LocalDateComparator.comparing 是 Java 8 引入的功能。

二、List.sort 和 Collections.sort 异同

1. 方法所属

  • testList.sort

    • List 接口中的一个方法(从 Java 8 开始引入)。

    • 直接作用于 List 对象本身。

  • Collections.sort

    • java.util.Collections 工具类中的一个静态方法。

    • 专门用于对 List 类型的集合进行排序。

2. 使用方式

  • testList.sort

    java 复制代码
    testList.sort(Comparator.comparing(Test::getStartTime));
    • 调用的是 List 的实例方法,直接在 List 上调用。
  • Collections.sort

java 复制代码
Collections.sort(testList, Comparator.comparing(Test::getStartTime));
  • 调用的是 Collections 的静态方法,需要显式传入 List 参数。

3. 是否修改原列表

  • testList.sort

    • 直接修改原列表的内容。
  • Collections.sort

    • 同样会直接修改原列表的内容。

4. 泛型 支持

  • testList.sort

    • 支持 Lambda 表达式和方法引用(Java 8+),代码更简洁。
  • Collections.sort

    • 同样支持 Lambda 表达式和方法引用,但在语法上稍微冗长一些。

5. 性能

  • testList.sortCollections.sort

    • 两者底层实现相同,均使用 Timsort 算法(一种基于归并排序的稳定排序算法),时间复杂度为 O(n log n)。

    • 因此,在性能上没有明显差异。

6. 适用场景

  • testList.sort

    • 更适合现代 Java 开发(Java 8+),代码更简洁直观。
  • Collections.sort

    • 在 Java 8 之前,这是唯一的排序方式。

    • 如果需要对非 List 类型的集合进行排序(例如 ArrayList 的父接口 List),仍然可以使用 Collections.sort

7. 示例代码对比

使用 testList.sort
java 复制代码
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class TestSort {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("C");
        list.add("A");
        list.add("B");

        // 使用 testList.sort 方法
        list.sort(Comparator.naturalOrder());

        System.out.println(list); // 输出: [A, B, C]
    }
}
使用 Collections.sort
java 复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class TestSort {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("C");
        list.add("A");
        list.add("B");

        // 使用 Collections.sort 方法
        Collections.sort(list, Comparator.naturalOrder());

        System.out.println(list); // 输出: [A, B, C]
    }
}

8. 总结

|---------------|------------------|------------------------|
| 特性 | testList.sort | Collections.sort |
| 所属 | List 接口的方法 | Collections 工具类的静态方法 |
| 调用方式 | 直接调用 List 实例方法 | 需要显式传入 List 参数 |
| 是否修改原列表 | 是 | 是 |
| 泛型 支持 | 支持 Lambda 和方法引用 | 支持 Lambda 和方法引用 |
| 性能 | 相同(Timsort 算法) | 相同(Timsort 算法) |
| 适用场景 | Java 8+ 推荐使用 | Java 8 之前的唯一选择 |

三、为对象多个属性进行排序

示例代码
java 复制代码
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

class Test {
    private String name;
    private LocalDate startTime;
    private int score;

    // 构造函数
    public Test(String name, LocalDate startTime, int score) {
        this.name = name;
        this.startTime = startTime;
        this.score = score;
    }

    // Getter 方法
    public String getName() {
        return name;
    }

    public LocalDate getStartTime() {
        return startTime;
    }

    public int getScore() {
        return score;
    }

    @Override
    public String toString() {
        return "Test{name='" + name + "', startTime=" + startTime + ", score=" + score + "}";
    }
}

public class MultiFieldSortExample {
    public static void main(String[] args) {
        // 创建一个 Test 对象列表
        List<Test> testList = new ArrayList<>();
        testList.add(new Test("Alice", LocalDate.of(2023, 1, 15), 80));
        testList.add(new Test("Bob", LocalDate.of(2023, 1, 10), 90));
        testList.add(new Test("Charlie", LocalDate.of(2023, 1, 10), 90));
        testList.add(new Test("David", LocalDate.of(2023, 1, 15), 70));
        testList.add(new Test("Eve", LocalDate.of(2023, 1, 10), 85));

        // 按多个字段排序
        testList.sort(Comparator.comparing(Test::getStartTime) // 按 startTime 升序
                            .thenComparing(test -> -test.getScore()) // 按 score 降序(负号实现)
                            .thenComparing(Test::getName)); // 按 name 升序

        // 输出排序后的结果
        testList.forEach(System.out::println);
    }
}
相关推荐
我是华为OD~HR~栗栗呀2 小时前
华为OD-23届-测试面经
java·前端·c++·python·华为od·华为·面试
yy7634966682 小时前
WPF 之 简单高效的Revit多语言支持方案
java·大数据·linux·服务器·wpf
我是华为OD~HR~栗栗呀2 小时前
华为od面经-23届-Java面经
java·c语言·c++·python·华为od·华为·面试
青云交6 小时前
Java 大视界 -- 基于 Java 的大数据机器学习模型在图像识别中的迁移学习与模型优化
java·大数据·迁移学习·图像识别·模型优化·deeplearning4j·机器学习模型
2501_909800817 小时前
Java 集合框架之 Set 接口
java·set接口
断剑zou天涯7 小时前
【算法笔记】暴力递归尝试
java·笔记·算法
Nobody_Cares8 小时前
JWT令牌
java
沐浴露z8 小时前
Kafka入门:基础架构讲解,安装与使用
java·分布式·kafka
神秘的土鸡8 小时前
从数据仓库到数据中台再到数据飞轮:我的数据技术成长之路
java·服务器·aigc·数据库架构·1024程序员节
vir028 小时前
P1928 外星密码(dfs)
java·数据结构·算法·深度优先·1024程序员节