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 值排后面
相关推荐
云烟成雨TD21 小时前
Spring AI Alibaba 1.x 系列【77】执行取消
java·人工智能·spring
醇氧1 天前
【Linux】Java 服务生产级部署指南:实现常驻后台、开机自启与系统服务化管理
java·开发语言
JAVA面经实录9171 天前
Netty 全套系统化学习文档(零基础到高阶面试完整版)
java·后端
菜鸟‍1 天前
LeetCode 1 27 和 704 || 两数之和 移除元素 二分查找
算法·leetcode·职场和发展
weixin_523185321 天前
Java面试高频题:Integer缓存机制与 equals、== 区别
java·缓存·面试
Hui Baby1 天前
MCP SSE协议发送注意
java
仙俊红1 天前
SpringBoot启动原理
java·spring boot·后端
星间都市山脉1 天前
Android STS(Security Test Suite)完整介绍与测试流程
android·java·linux·windows·ubuntu·android studio·androidx
namexingyun1 天前
拆解Fable 5三重安全护栏:模型路由、蒸馏防护与生物安全分类器的技术原理 - 微元算力(weytoken)
java·人工智能·python·安全·架构·ai编程
地铁潜行者1 天前
加了幂等表,为什么消息重试反而不执行了?聊聊 MQ 消费幂等的边界
java·后端