Hutool Hutool
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
  • 快速入门

  • 核心(hutool-core)

    • AI(Hutool-ai)

    • 注解(annotation)

    • 数组(array)

    • JavaBean(bean)

    • 缓存(cache)

    • 类加载器(classloader)

    • 编码解码(codec)

    • 集合(collection)

    • 比较器(comparator)

      • 简介
      • 比较工具-CompareUtil
      • 比较器实现
        • 📚 介绍
        • 🔧 比较器实现类详解
          • 1. 基础比较器
          • 1.1 NullComparator
          • 1.2 StrLengthComparator
          • 1.3 WindowsExplorerStringComparator
          • 2. 属性比较器
          • 2.1 PropertyComparator
          • 2.2 FieldComparator
          • 2.3 FieldsComparator
          • 3. 高级比较器
          • 3.1 FuncComparator
          • 3.2 ComparatorChain
          • 4. 特定用途比较器
          • 4.1 PinyinComparator
          • 4.2 VersionComparator
          • 4.3 LocaleComparator
          • 5. 索引相关比较器
          • 5.1 IndexedComparator
          • 5.2 ArrayIndexedComparator
          • 5.3 InstanceComparator
        • 🚀 综合示例
          • 示例:复杂对象排序
        • 🎯 比较器选择指南
        • 📌 注意事项
        • 🚀 总结
    • 压缩(compress)

    • 类型转换(convert)

    • 数据(data)

    • 日期时间(date)

    • 异常(exception)

    • 函数(func)

    • IO流(io)

    • 语言特性(lang)

    • Map(map)

    • 数字数学(math)

    • 网络(net)

    • 对象池(pool)

    • 反射(reflect)

    • 正则(regex)

    • 服务提供(spi)

    • 聚合操作(stream)

    • 字符串文本(text)

    • 并发和线程(thread)

    • 树结构(tree)

    • 工具集合(util)

    • XML操作(xml)

  • 定时任务(hutool-cron)

  • 加密(hutool-crypto)

  • 数据库(hutool-db)

  • 扩展(hutool-extra)

  • HTTP(hutool-http)

  • 日志(hutool-log)

  • 配置文件(hutool-setting)

  • JSON(hutool-json)

  • Office办公(hutool-poi)

  • 套接字(hutool-socket)

  • GUI(hutool-swing)

  • 指南
  • 核心(hutool-core)
  • 比较器(comparator)
Hutool
2026-01-14
目录

比较器实现

# 📚 介绍

Hutool提供了丰富的比较器实现,涵盖了各种比较场景,从简单的属性比较到复杂的多字段比较。这些比较器实现类继承自Comparator接口,提供了不同的比较逻辑,可以直接用于集合排序、对象比较等场景。

# 🔧 比较器实现类详解

# 1. 基础比较器

# 1.1 NullComparator

功能:处理空值的比较器,用于确定null值在比较中的位置

核心方法:

  • NullComparator(boolean nullGreater):构造方法,指定null值是否大于非null值
  • compare(T o1, T o2):比较两个对象,处理空值情况

示例:

// 创建NullComparator,null值小于非null值
NullComparator<String> nullComparator = new NullComparator<>(false);

String str1 = null;
String str2 = "abc";

// 比较null和非null对象
int result1 = nullComparator.compare(str1, str2);
int result2 = nullComparator.compare(str2, str1);

Console.log(result1); // 负数,表示 str1 < str2
Console.log(result2); // 正数,表示 str2 > str1

适用场景:

  • 需要自定义null值在比较中的位置
  • 集合排序时处理null元素

# 1.2 StrLengthComparator

功能:字符串长度比较器,根据字符串长度进行比较

核心方法:

  • compare(String o1, String o2):比较两个字符串的长度

示例:

// 创建字符串长度比较器
StrLengthComparator lengthComparator = new StrLengthComparator();

String str1 = "abc";
String str2 = "defgh";

// 比较两个字符串的长度
int result = lengthComparator.compare(str1, str2);
Console.log(result); // 负数,表示 str1 的长度 < str2 的长度

适用场景:

  • 按照字符串长度进行排序
  • 比较字符串的长度大小

# 1.3 WindowsExplorerStringComparator

功能:Windows资源管理器风格的字符串比较器,模仿Windows资源管理器的文件排序方式

核心方法:

  • compare(String o1, String o2):按照Windows资源管理器风格比较两个字符串

示例:

// 创建Windows资源管理器字符串比较器
WindowsExplorerStringComparator weComparator = new WindowsExplorerStringComparator();

// 创建文件列表
List<String> files = Arrays.asList(
    "file10.txt",
    "file2.txt",
    "file1.txt",
    "File2.txt",
    "File1.txt"
);

// 使用比较器排序
files.sort(weComparator);

// 输出排序结果
Console.log("Windows资源管理器风格排序:");
f files.forEach(file -> Console.log(file));
// 输出:
// File1.txt
// file1.txt
// File2.txt
// file2.txt
// file10.txt

适用场景:

  • 需要模仿Windows资源管理器的文件排序方式
  • 对包含数字的字符串进行自然排序

# 2. 属性比较器

# 2.1 PropertyComparator

功能:属性比较器,根据对象的属性进行比较

核心方法:

  • PropertyComparator(String property):构造方法,指定要比较的属性名
  • PropertyComparator(String property, boolean ignoreCase):构造方法,指定要比较的属性名和是否忽略大小写
  • compare(T o1, T o2):比较两个对象的指定属性

示例:

// 创建用户类
class User {
    private String name;
    private int age;

    // getter and setter
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

// 创建用户列表
List<User> users = Arrays.asList(
    new User("Alice", 25),
    new User("Bob", 20),
    new User("Charlie", 30)
);

// 使用属性比较器按年龄排序
PropertyComparator<User> ageComparator = new PropertyComparator<>("age");
users.sort(ageComparator);

// 输出排序结果
users.forEach(user -> Console.log(user.getName() + ": " + user.getAge()));
// 输出:
// Bob: 20
// Alice: 25
// Charlie: 30

适用场景:

  • 根据对象的单个属性进行排序
  • 动态指定要比较的属性

# 2.2 FieldComparator

功能:字段比较器,根据对象的字段进行比较(直接访问字段,不通过getter方法)

核心方法:

  • FieldComparator(String fieldName):构造方法,指定要比较的字段名
  • compare(T o1, T o2):比较两个对象的指定字段

示例:

// 创建用户类,使用public字段
class User {
    public String name;
    public int age;

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

// 创建用户列表
List<User> users = Arrays.asList(
    new User("Alice", 25),
    new User("Bob", 20),
    new User("Charlie", 30)
);

// 使用字段比较器按年龄排序
FieldComparator<User> fieldComparator = new FieldComparator<>("age");
users.sort(fieldComparator);

// 输出排序结果
users.forEach(user -> Console.log(user.name + ": " + user.age));

适用场景:

  • 比较对象的public字段
  • 性能要求较高的场景(直接访问字段比通过getter方法快)

# 2.3 FieldsComparator

功能:多字段比较器,根据对象的多个字段进行比较

核心方法:

  • FieldsComparator(String... fieldNames):构造方法,指定要比较的多个字段名
  • compare(T o1, T o2):比较两个对象的多个字段

示例:

// 创建产品类
class Product {
    private String category;
    private String name;
    private double price;

    // getter and setter
    public Product(String category, String name, double price) {
        this.category = category;
        this.name = name;
        this.price = price;
    }

    public String getCategory() {
        return category;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

// 创建产品列表
List<Product> products = Arrays.asList(
    new Product("Electronics", "Laptop", 999.99),
    new Product("Electronics", "Smartphone", 699.99),
    new Product("Books", "Java Programming", 29.99),
    new Product("Electronics", "Headphones", 199.99),
    new Product("Furniture", "Desk", 499.99)
);

// 使用多字段比较器,先按分类,再按价格
FieldsComparator<Product> fieldsComparator = new FieldsComparator<>("category", "price");
products.sort(fieldsComparator);

// 输出排序结果
products.forEach(product -> Console.log(
    product.getCategory() + ": " + product.getName() + " - $" + product.getPrice()
));

适用场景:

  • 根据多个字段进行排序
  • 需要组合多个字段的比较逻辑

# 3. 高级比较器

# 3.1 FuncComparator

功能:函数比较器,通过函数定义比较逻辑

核心方法:

  • FuncComparator(Function<? super T, ? extends U> keyExtractor, Comparator<? super U> keyComparator):构造方法,指定键提取函数和键比较器
  • compare(T o1, T o2):使用函数比较两个对象

示例:

// 创建学生类
class Student {
    private String name;
    private List<Integer> scores;

    // getter and setter
    public Student(String name, List<Integer> scores) {
        this.name = name;
        this.scores = scores;
    }

    public String getName() {
        return name;
    }

    public List<Integer> getScores() {
        return scores;
    }
}

// 创建学生列表
List<Student> students = Arrays.asList(
    new Student("Alice", Arrays.asList(85, 90, 95)),
    new Student("Bob", Arrays.asList(75, 80, 85)),
    new Student("Charlie", Arrays.asList(90, 95, 100))
);

// 创建函数比较器,比较学生的平均成绩
FuncComparator<Student, Double> avgScoreComparator = new FuncComparator<>(
    student -> student.getScores().stream().mapToInt(Integer::intValue).average().orElse(0.0),
    Comparator.reverseOrder() // 降序排序
);

// 使用函数比较器排序
students.sort(avgScoreComparator);

// 输出排序结果
students.forEach(student -> {
    double avgScore = student.getScores().stream().mapToInt(Integer::intValue).average().orElse(0.0);
    Console.log(student.getName() + " - 平均成绩: " + avgScore);
});

适用场景:

  • 需要自定义复杂的比较逻辑
  • 比较对象的计算属性
  • 函数式编程风格的比较

# 3.2 ComparatorChain

功能:比较器链,将多个比较器组合成一个,按顺序执行比较

核心方法:

  • ComparatorChain():构造方法,创建空的比较器链
  • ComparatorChain(Comparator<? super E>... comparators):构造方法,创建包含指定比较器的比较器链
  • addComparator(Comparator<? super E> comparator):添加比较器到链末尾
  • compare(E o1, E o2):按顺序执行比较器链中的比较器

示例:

// 创建用户列表
List<User> users = Arrays.asList(
    new User("Alice", 25, "F"),
    new User("Bob", 20, "M"),
    new User("Charlie", 30, "M"),
    new User("David", 25, "M"),
    new User("Eve", 20, "F")
);

// 创建比较器链
ComparatorChain<User> comparatorChain = new ComparatorChain<>();

// 添加比较器:先按性别,再按年龄降序,最后按名称
comparatorChain.addComparator(Comparator.comparing(User::getGender));
comparatorChain.addComparator(Comparator.comparing(User::getAge).reversed());
comparatorChain.addComparator(Comparator.comparing(User::getName));

// 使用比较器链排序
users.sort(comparatorChain);

// 输出排序结果
users.forEach(user -> Console.log(
    user.getName() + ", " + user.getAge() + ", " + user.getGender()
));

适用场景:

  • 需要组合多个比较器的逻辑
  • 动态构建比较器链
  • 复杂的排序规则

# 4. 特定用途比较器

# 4.1 PinyinComparator

功能:拼音比较器,根据汉字的拼音进行比较

核心方法:

  • compare(String o1, String o2):比较两个汉字字符串的拼音

示例:

// 创建拼音比较器
PinyinComparator pinyinComparator = new PinyinComparator();

// 创建汉字列表
List<String> chineseNames = Arrays.asList("张三", "李四", "王五", "赵六", "钱七");

// 使用拼音比较器排序
chineseNames.sort(pinyinComparator);

// 输出排序结果
Console.log("按拼音排序:");
chineseNames.forEach(name -> Console.log(name));

适用场景:

  • 汉字字符串的排序
  • 按拼音字母顺序排列中文内容

# 4.2 VersionComparator

功能:版本比较器,比较版本号的大小

核心方法:

  • compare(String version1, String version2):比较两个版本号

示例:

// 创建版本比较器
VersionComparator versionComparator = new VersionComparator();

// 比较版本号
int result1 = versionComparator.compare("1.0.0", "1.1.0");
int result2 = versionComparator.compare("2.0.0", "1.9.9");
int result3 = versionComparator.compare("1.0.0-alpha", "1.0.0-beta");

Console.log("1.0.0 vs 1.1.0: " + result1); // 负数,表示 1.0.0 < 1.1.0
Console.log("2.0.0 vs 1.9.9: " + result2); // 正数,表示 2.0.0 > 1.9.9
Console.log("1.0.0-alpha vs 1.0.0-beta: " + result3); // 负数,表示 alpha < beta

适用场景:

  • 软件版本号比较
  • 版本号排序
  • 版本兼容性检查

# 4.3 LocaleComparator

功能:本地化比较器,考虑不同地区的比较规则

核心方法:

  • LocaleComparator(Locale locale):构造方法,指定本地化信息
  • compare(String o1, String o2):按照指定本地化规则比较两个字符串

示例:

// 创建不同地区的本地化比较器
LocaleComparator usComparator = new LocaleComparator(Locale.US);
LocaleComparator frComparator = new LocaleComparator(Locale.FRANCE);

String str1 = "café";
String str2 = "cafe";

// 比较两个字符串在不同地区的排序结果
int resultUS = usComparator.compare(str1, str2);
int resultFR = frComparator.compare(str1, str2);

Console.log("US locale: " + resultUS);
Console.log("France locale: " + resultFR);

适用场景:

  • 国际化应用中的字符串比较
  • 需要考虑不同地区排序规则的场景

# 5. 索引相关比较器

# 5.1 IndexedComparator

功能:索引比较器,用于比较带有索引的对象

核心方法:

  • compare(IndexedObject<T> o1, IndexedObject<T> o2):比较两个带有索引的对象

示例:

// 创建IndexedObject列表
List<IndexedObject<String>> indexedObjects = Arrays.asList(
    new IndexedObject<>("c", 2),
    new IndexedObject<>("a", 0),
    new IndexedObject<>("b", 1)
);

// 使用索引比较器排序
IndexedComparator<String> indexedComparator = new IndexedComparator<>();
indexedObjects.sort(indexedComparator);

// 输出排序结果
indexedObjects.forEach(obj -> Console.log(obj.getValue() + " (index: " + obj.getIndex() + "));
// 输出:
// a (index: 0)
// b (index: 1)
// c (index: 2)

适用场景:

  • 比较带有索引的对象
  • 索引排序场景

# 5.2 ArrayIndexedComparator

功能:数组索引比较器,用于比较数组中的元素并记录索引

核心方法:

  • compare(int[] o1, int[] o2):比较两个数组索引

示例:

// 创建数组
String[] array = {"c", "a", "b"};

// 创建数组索引比较器
ArrayIndexedComparator arrayComparator = new ArrayIndexedComparator(array);

// 创建索引数组
int[][] indexes = new int[array.length][2];
for (int i = 0; i < array.length; i++) {
    indexes[i][0] = i;
    indexes[i][1] = i;
}

// 使用数组索引比较器排序
Arrays.sort(indexes, arrayComparator);

// 输出排序结果
Console.log("排序后的数组:");
for (int[] index : indexes) {
    Console.log(array[index[0]]);
}

适用场景:

  • 数组排序并保留原始索引
  • 需要知道元素排序前后位置变化的场景

# 5.3 InstanceComparator

功能:实例比较器,用于比较对象的实例顺序

核心方法:

  • compare(T o1, T o2):比较两个对象的实例顺序

示例:

// 创建实例比较器
InstanceComparator<String> instanceComparator = new InstanceComparator<>();

String str1 = new String("abc");
String str2 = new String("abc");
String str3 = str1;

// 比较对象实例
int result1 = instanceComparator.compare(str1, str2);
int result2 = instanceComparator.compare(str1, str3);

Console.log(result1); // 非零值,表示 str1 和 str2 是不同实例
Console.log(result2); // 0,表示 str1 和 str3 是相同实例

适用场景:

  • 比较对象的引用相等性
  • 需要区分不同实例的场景

# 🚀 综合示例

# 示例:复杂对象排序

// 创建员工类
class Employee {
    private String department;
    private String name;
    private int age;
    private double salary;

    // getter and setter
    public Employee(String department, String name, int age, double salary) {
        this.department = department;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getDepartment() {
        return department;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public double getSalary() {
        return salary;
    }
}

public class ComplexSortExample {
    public static void main(String[] args) {
        // 创建员工列表
        List<Employee> employees = Arrays.asList(
            new Employee("IT", "Alice", 30, 8000.0),
            new Employee("HR", "Bob", 25, 6000.0),
            new Employee("IT", "Charlie", 35, 10000.0),
            new Employee("Finance", "David", 40, 9000.0),
            new Employee("HR", "Eve", 28, 6500.0),
            new Employee("IT", "Frank", 26, 7000.0)
        );

        Console.log("原始列表:");
        printEmployees(employees);

        // 示例1:使用PropertyComparator按部门排序
        employees.sort(new PropertyComparator<>("department"));
        Console.log("\n按部门排序:");
        printEmployees(employees);

        // 示例2:使用ComparatorChain组合多个比较器
        ComparatorChain<Employee> comparatorChain = new ComparatorChain<>();
        comparatorChain.addComparator(Comparator.comparing(Employee::getDepartment));
        comparatorChain.addComparator(Comparator.comparing(Employee::getSalary).reversed());
        comparatorChain.addComparator(Comparator.comparing(Employee::getAge));

        employees.sort(comparatorChain);
        Console.log("\n按部门、薪资降序、年龄排序:");
        printEmployees(employees);

        // 示例3:使用FuncComparator计算属性排序
        FuncComparator<Employee, Double> bonusComparator = new FuncComparator<>(
            employee -> employee.getSalary() * 0.1, // 计算奖金
            Comparator.reverseOrder() // 按奖金降序排序
        );

        employees.sort(bonusComparator);
        Console.log("\n按奖金降序排序:");
        employees.forEach(employee -> {
            double bonus = employee.getSalary() * 0.1;
            Console.log(
                employee.getName() + " (" + employee.getDepartment() + ") - 薪资: $" +
                employee.getSalary() + " - 奖金: $" + bonus
            );
        });
    }

    private static void printEmployees(List<Employee> employees) {
        employees.forEach(employee -> Console.log(
            employee.getName() + " (" + employee.getDepartment() + "), " +
            employee.getAge() + "岁, 薪资: $" + employee.getSalary()
        ));
    }
}

# 🎯 比较器选择指南

比较场景 推荐比较器
处理null值 NullComparator
字符串长度比较 StrLengthComparator
Windows风格字符串比较 WindowsExplorerStringComparator
单个属性比较 PropertyComparator
多个属性比较 FieldsComparator
直接字段比较 FieldComparator
自定义比较逻辑 FuncComparator
组合多个比较器 ComparatorChain
汉字拼音比较 PinyinComparator
版本号比较 VersionComparator
本地化比较 LocaleComparator
索引相关比较 IndexedComparator, ArrayIndexedComparator
实例比较 InstanceComparator

# 📌 注意事项

  1. 性能考虑:不同比较器的性能有所不同,直接字段比较(FieldComparator)比属性比较(PropertyComparator)快
  2. 线程安全:所有比较器实现类都是线程安全的,可以在多线程环境下安全使用
  3. 空值处理:使用比较器时,注意处理null值情况,避免NullPointerException
  4. 类型安全:确保比较器的类型参数与实际使用的对象类型匹配
  5. 自定义比较器:如果现有比较器不能满足需求,可以实现Comparator接口创建自定义比较器

# 🚀 总结

Hutool提供了丰富的比较器实现,涵盖了各种比较场景,从简单的空值处理到复杂的多字段比较。这些比较器实现类可以直接用于集合排序、对象比较等场景,简化了开发工作。

通过合理选择和组合比较器,可以实现各种复杂的排序逻辑,满足不同的业务需求。无论是简单的属性比较,还是复杂的多字段组合比较,Hutool的比较器都能提供便捷的解决方案。

在实际开发中,根据具体的比较需求选择合适的比较器,可以提高代码的可读性和性能,减少重复代码的编写。

比较工具-CompareUtil
简介

← 比较工具-CompareUtil 简介→

Theme by Vdoing | Copyright © 2025-2026 Hutool | Apache-2.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式