比较工具-CompareUtil
# 📚 介绍
CompareUtil 是 Hutool 核心模块中的比较工具类,它提供了丰富的比较方法,包括基本类型比较、对象比较、空值处理、数组比较和集合比较等功能,为 Java 开发者提供了便捷的比较解决方案。
# 设计理念
- 简化比较:提供简洁的 API,一行代码即可完成复杂的比较操作
- 全面覆盖:涵盖几乎所有常用的比较场景
- 空值安全:自动处理空值情况,避免 NullPointerException
- 类型安全:提供类型安全的比较方法
- 高性能:底层实现经过优化,性能优异
- 线程安全:所有方法都是线程安全的,可以在多线程环境下安全使用
# 🔧 核心方法详解
# 1. 基本类型比较
# compare(byte x, byte y)
功能:比较两个 byte 类型的值
参数:
x:第一个要比较的值y:第二个要比较的值
返回值:如果 x < y 返回负数;如果 x == y 返回 0;如果 x > y 返回正数
示例:
byte a = 10;
byte b = 20;
// 比较两个 byte 值
int result = CompareUtil.compare(a, b);
Console.log(result); // 负数,表示 a < b
# compare(short x, short y)
功能:比较两个 short 类型的值
参数:
x:第一个要比较的值y:第二个要比较的值
返回值:比较结果
示例:
short a = 100;
short b = 200;
int result = CompareUtil.compare(a, b);
Console.log(result); // 负数,表示 a < b
# compare(int x, int y)
功能:比较两个 int 类型的值
参数:
x:第一个要比较的值y:第二个要比较的值
返回值:比较结果
示例:
int a = 1000;
int b = 2000;
int result = CompareUtil.compare(a, b);
Console.log(result); // 负数,表示 a < b
# compare(long x, long y)
功能:比较两个 long 类型的值
参数:
x:第一个要比较的值y:第二个要比较的值
返回值:比较结果
示例:
long a = 1000000000L;
long b = 2000000000L;
int result = CompareUtil.compare(a, b);
Console.log(result); // 负数,表示 a < b
# compare(float x, float y)
功能:比较两个 float 类型的值
参数:
x:第一个要比较的值y:第二个要比较的值
返回值:比较结果
示例:
float a = 10.5f;
float b = 20.5f;
int result = CompareUtil.compare(a, b);
Console.log(result); // 负数,表示 a < b
# compare(double x, double y)
功能:比较两个 double 类型的值
参数:
x:第一个要比较的值y:第二个要比较的值
返回值:比较结果
示例:
double a = 10.5;
double b = 20.5;
int result = CompareUtil.compare(a, b);
Console.log(result); // 负数,表示 a < b
# compare(char x, char y)
功能:比较两个 char 类型的值
参数:
x:第一个要比较的值y:第二个要比较的值
返回值:比较结果
示例:
char a = 'a';
char b = 'b';
int result = CompareUtil.compare(a, b);
Console.log(result); // 负数,表示 a < b
# 2. 对象比较
# compare(T obj1, T obj2)
功能:比较两个对象
参数:
obj1:第一个要比较的对象obj2:第二个要比较的对象
返回值:比较结果
示例:
String str1 = "abc";
String str2 = "def";
// 比较两个字符串
int result = CompareUtil.compare(str1, str2);
Console.log(result); // 负数,表示 str1 < str2
// 比较两个日期
Date date1 = new Date();
Date date2 = new Date(System.currentTimeMillis() + 1000);
result = CompareUtil.compare(date1, date2);
Console.log(result); // 负数,表示 date1 < date2
# compare(T obj1, T obj2, Comparator<? super T> comparator)
功能:使用指定的比较器比较两个对象
参数:
obj1:第一个要比较的对象obj2:第二个要比较的对象comparator:用于比较对象的比较器
返回值:比较结果
示例:
List<String> list1 = Arrays.asList("a", "b", "c");
List<String> list2 = Arrays.asList("d", "e");
// 使用长度比较器比较两个列表
int result = CompareUtil.compare(list1, list2, Comparator.comparingInt(List::size));
Console.log(result); // 正数,表示 list1 的长度 > list2 的长度
# 3. 空值处理
# compareWithNull(T obj1, T obj2, boolean nullGreater)
功能:比较两个对象,支持处理空值
参数:
obj1:第一个要比较的对象obj2:第二个要比较的对象nullGreater:如果为 true,则 null 大于非 null 对象;否则 null 小于非 null 对象
返回值:比较结果
示例:
String str1 = null;
String str2 = "abc";
// 比较 null 和非 null 对象,null 小于非 null 对象
int result1 = CompareUtil.compareWithNull(str1, str2, false);
Console.log(result1); // 负数,表示 str1 < str2
// 比较 null 和非 null 对象,null 大于非 null 对象
int result2 = CompareUtil.compareWithNull(str1, str2, true);
Console.log(result2); // 正数,表示 str1 > str2
# 4. 数组比较
# compare(byte[] array1, byte[] array2)
功能:比较两个 byte 数组
参数:
array1:第一个要比较的数组array2:第二个要比较的数组
返回值:比较结果
示例:
byte[] array1 = {1, 2, 3};
byte[] array2 = {1, 2, 4};
int result = CompareUtil.compare(array1, array2);
Console.log(result); // 负数,表示 array1 < array2
# compare(int[] array1, int[] array2)
功能:比较两个 int 数组
参数:
array1:第一个要比较的数组array2:第二个要比较的数组
返回值:比较结果
示例:
int[] array1 = {1, 2, 3};
int[] array2 = {1, 2, 3};
int result = CompareUtil.compare(array1, array2);
Console.log(result); // 0,表示 array1 == array2
# 5. 比较器相关方法
# nullsFirst(Comparator<? super T> comparator)
功能:返回一个比较器,将 null 值视为小于非 null 值
参数:
comparator:用于比较非 null 值的比较器
返回值:处理 null 的比较器
示例:
List<String> list = Arrays.asList("b", null, "a", "c");
// 使用 nullsFirst 比较器排序
list.sort(CompareUtil.nullsFirst(String::compareTo));
Console.log(list); // [null, a, b, c]
# nullsLast(Comparator<? super T> comparator)
功能:返回一个比较器,将 null 值视为大于非 null 值
参数:
comparator:用于比较非 null 值的比较器
返回值:处理 null 的比较器
示例:
List<String> list = Arrays.asList("b", null, "a", "c");
// 使用 nullsLast 比较器排序
list.sort(CompareUtil.nullsLast(String::compareTo));
Console.log(list); // [a, b, c, null]
# 🚀 综合示例
# 示例1:对象列表排序
public class CompareUtilTest {
public static void main(String[] args) {
// 创建用户列表
List<User> users = Arrays.asList(
new User("Alice", 25),
new User("Bob", 20),
new User("Charlie", 30),
new User(null, 22),
new User("David", null)
);
Console.log("原始列表:");
users.forEach(user -> Console.log(user.getName() + ", " + user.getAge()));
// 按名称排序,null 放在前面
users.sort(Comparator.comparing(User::getName, CompareUtil.nullsFirst(String::compareTo)));
Console.log("\n按名称排序(null 在前):");
users.forEach(user -> Console.log(user.getName() + ", " + user.getAge()));
// 按年龄排序,null 放在后面
users.sort(Comparator.comparing(User::getAge, CompareUtil.nullsLast(Integer::compareTo)));
Console.log("\n按年龄排序(null 在后):");
users.forEach(user -> Console.log(user.getName() + ", " + user.getAge()));
}
static class User {
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
}
# 示例2:复杂对象比较
public class ComplexCompareTest {
public static void main(String[] args) {
// 创建产品列表
List<Product> products = Arrays.asList(
new Product("Laptop", "Electronics", 999.99),
new Product("Smartphone", "Electronics", 699.99),
new Product("Book", "Books", 29.99),
new Product("Headphones", "Electronics", 199.99),
new Product("Desk", "Furniture", 499.99)
);
Console.log("原始列表:");
products.forEach(product -> Console.log(product.getName() + " - " + product.getCategory() + " - $" + product.getPrice()));
// 先按分类排序,再按价格降序排序
products.sort(
Comparator.comparing(Product::getCategory)
.thenComparing(Product::getPrice, Comparator.reverseOrder())
);
Console.log("\n按分类和价格排序:");
products.forEach(product -> Console.log(product.getName() + " - " + product.getCategory() + " - $" + product.getPrice()));
}
static class Product {
private String name;
private String category;
private double price;
public Product(String name, String category, double price) {
this.name = name;
this.category = category;
this.price = price;
}
public String getName() {
return name;
}
public String getCategory() {
return category;
}
public double getPrice() {
return price;
}
}
}
# 🎯 设计优势
- 简化比较:提供了统一的比较接口,简化了各种类型的比较操作
- 空值安全:自动处理空值情况,避免了 NullPointerException
- 全面覆盖:涵盖了基本类型、对象、数组等各种比较场景
- 类型安全:提供了类型安全的比较方法,避免了类型转换错误
- 高性能:底层实现经过优化,性能优异
- 线程安全:所有方法都是线程安全的,可以在多线程环境下安全使用
- 易于扩展:支持自定义比较器,便于扩展新的比较逻辑
# 📌 注意事项
- 对象比较:比较对象时,确保对象实现了 Comparable 接口或提供了自定义比较器
- 空值处理:在比较可能为 null 的对象时,使用 compareWithNull 方法或 nullsFirst/nullsLast 比较器
- 数组比较:数组比较时,会逐元素比较,直到找到不同的元素或比较完所有元素
- 性能考虑:对于大规模数据的比较,考虑使用高效的比较器实现
- 类型转换:比较不同类型的值时,注意类型转换可能带来的精度损失
- 版本兼容性:不同版本的 Hutool 可能对某些比较方法的实现有所调整,注意版本兼容性
# 🚀 总结
CompareUtil 是一个功能强大、使用便捷的比较工具类,为 Java 开发者提供了丰富的比较解决方案。它简化了各种类型的比较操作,自动处理空值情况,提供了类型安全的比较方法,性能优异,线程安全。
无论是简单的基本类型比较,还是复杂的对象列表排序,CompareUtil 都能轻松应对。通过合理使用 CompareUtil,可以简化比较操作的开发工作,提高开发效率,同时保证比较的准确性和性能。
CompareUtil 是 Hutool 比较器模块中的核心工具类,与各种比较器实现类一起,构成了完整的比较解决方案,为 Java 开发者提供了丰富的比较工具。