Java排序方法全解析

一、核心原则

Java 中排序的两种方式:

  1. 自然排序 :类实现 Comparable 接口(如 StringInteger

  2. 定制排序 :传入 Comparator 比较器(Lambda 表达式)

二、各种数据结构的排序方法

1. 数组(Array)

java 复制代码
// 基本类型数组(只能升序)
int[] arr = {5, 2, 8, 1};
Arrays.sort(arr);  // [1, 2, 5, 8]

// 对象数组(可定制排序)
String[] strs = {"banana", "apple", "pear"};
Arrays.sort(strs);  // 自然排序:[apple, banana, pear]
Arrays.sort(strs, (a, b) -> b.length() - a.length());  // 按长度降序

// 二维数组
int[][] matrix = {{5,2}, {1,3}, {2,1}};
Arrays.sort(matrix, (a, b) -> a[0] - b[0]);  // 按第一列排序

2. List集合

java 复制代码
List<Integer> list = new ArrayList<>(Arrays.asList(5, 2, 8, 1));

// 方式1:Collections.sort()
Collections.sort(list);  // 升序
Collections.sort(list, (a, b) -> b - a);  // 降序

// 方式2:List.sort()(推荐)
list.sort((a, b) -> a - b);  // 升序
list.sort(Comparator.naturalOrder());  // 自然顺序
list.sort(Comparator.reverseOrder());  // 降序

// 方式3:Stream(不修改原集合)
List<Integer> sorted = list.stream().sorted().collect(Collectors.toList());

3. Map排序

Map 本身无序,但可以对其 keySetvaluesentrySet 排序。

java 复制代码
Map<String, Integer> map = new HashMap<>();
map.put("apple", 5);
map.put("banana", 2);
map.put("pear", 8);

// 1. 按 Key 排序
List<String> sortedKeys = new ArrayList<>(map.keySet());
Collections.sort(sortedKeys);  // [apple, banana, pear]

// 2. 按 Value 排序
List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());
entries.sort((a, b) -> a.getValue() - b.getValue());
// 结果:banana=2, apple=5, pear=8

// 3. 使用 Stream(更优雅)
Map<String, Integer> sortedByKey = map.entrySet().stream()
    .sorted(Map.Entry.comparingByKey())
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (e1, e2) -> e1,
        LinkedHashMap::new  // 保持顺序
    ));

// 4. 使用 TreeMap(自动排序)
Map<String, Integer> treeMap = new TreeMap<>(map);  // 按 key 自然排序
Map<String, Integer> treeMapDesc = new TreeMap<>((a, b) -> b.compareTo(a));  // 降序
treeMapDesc.putAll(map);

4. Set排序

Set 无序,可以转成 List 排序:

java 复制代码
Set<Integer> set = new HashSet<>(Arrays.asList(5, 2, 8, 1));

// 转 List 排序
List<Integer> list = new ArrayList<>(set);
Collections.sort(list);

// 使用 TreeSet(自动排序)
Set<Integer> treeSet = new TreeSet<>(set);  // 升序
Set<Integer> treeSetDesc = new TreeSet<>((a, b) -> b - a);  // 降序
treeSetDesc.addAll(set);

// Stream 排序
List<Integer> sorted = set.stream().sorted().collect(Collectors.toList());

5. 对象数组/List 排序

java 复制代码
class Person {
    String name;
    int age;
    Person(String name, int age) { this.name = name; this.age = age; }
}

List<Person> people = Arrays.asList(
    new Person("Alice", 30),
    new Person("Bob", 25),
    new Person("Charlie", 35)
);

// 1. 按年龄升序
people.sort((p1, p2) -> p1.age - p2.age);

// 2. 按年龄降序
people.sort((p1, p2) -> p2.age - p1.age);

// 3. 多级排序:先按年龄,再按名字
people.sort((p1, p2) -> {
    if (p1.age != p2.age) return p1.age - p2.age;
    return p1.name.compareTo(p2.name);
});

// 4. 使用 Comparator 链式调用(推荐)
people.sort(Comparator
    .comparingInt((Person p) -> p.age)
    .thenComparing(p -> p.name));

// 5. 让 Person 实现 Comparable
class Person implements Comparable<Person> {
    // ...
    @Override
    public int compareTo(Person other) {
        return this.age - other.age;  // 自然排序按年龄
    }
}
Collections.sort(people);  // 使用自然排序

6. 优先队列

java 复制代码
// 默认是小顶堆(升序)
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(5); pq.add(2); pq.add(8);
// 出队顺序:2, 5, 8

// 大顶堆(降序)
PriorityQueue<Integer> pqDesc = new PriorityQueue<>((a, b) -> b - a);

// 自定义对象
PriorityQueue<Person> pqPerson = new PriorityQueue<>(
    (p1, p2) -> p1.age - p2.age  // 按年龄小的优先
);

// 或使用 Comparator
PriorityQueue<int[]> pqArray = new PriorityQueue<>(
    Comparator.comparingInt(a -> a[0])  // 按数组第一个元素
);

三、Comparator 常用方法速查

java 复制代码
// 1. 基本比较器
Comparator.comparingInt(a -> a.age)           // 升序
Comparator.comparingInt(a -> -a.age)          // 降序
Comparator.comparing(Person::getName)         // 按字符串升序
Comparator.comparing(Person::getName, String.CASE_INSENSITIVE_ORDER)  // 忽略大小写

// 2. 链式调用
Comparator.comparingInt(Person::getAge)
          .thenComparing(Person::getName)
          .thenComparingInt(Person::getScore)
          .reversed();  // 整体反转

// 3. 工具方法
Comparator.naturalOrder()     // 自然排序(需实现 Comparable)
Comparator.reverseOrder()     // 自然排序的反转
Comparator.nullsFirst(cmp)    // null 值排前面
Comparator.nullsLast(cmp)     // null 值排后面
相关推荐
Robot_Nav14 分钟前
MPPI 局部规划器实验设计讲解
人工智能·算法·mppi
Lhappy嘻嘻37 分钟前
Java 并发编程(六)|并发进阶高频:CAS、锁升级
java·开发语言
mingo_敏42 分钟前
Mean-Teacher 均值教师自训练框架详解
算法·均值算法
要开心吖ZSH1 小时前
MVCC 进阶:快照读 vs 当前读、幻读与 Next-Key Lock
java·数据库·sql·mysql·mvcc
京韵养生记1 小时前
【无标题】
java·服务器·前端
小强库计算机毕业设计1 小时前
源码分享Spring Boot + Vue3 的校园社团管理系统
java·spring boot·后端·计算机毕业设计
星空露珠1 小时前
迷你世界UGc3.0脚本Wiki[剧情动画模块管理接口 Timeline]
开发语言·数据结构·算法·游戏·lua
笨笨没好名字1 小时前
Leetcode刷题python3版第一周(下)
linux·算法·leetcode
格子软件1 小时前
2026年分布式GEO代理流量调度:源码级状态机防重挂实战
java·vue.js·人工智能·spring boot·分布式·vue
hj2862511 小时前
Docker 容器化技术标准化笔记
java·笔记·docker