如何理解Java中比较器引发的顺序?
How to understand the order induced by the comparator in Java?
我对 Java 中的比较器和 Collections.sort() 感到非常困惑。
我不明白比较器引起的顺序。我不清楚比较函数应该 return 哪个数字来获得排序方向。我也不知道 Collections 将如何使用该比较结果对输入数据进行排序。我应该记住它们吗?有什么更容易理解的吗?谁能帮我解释一下?谢谢。
public int compare(Obj a, Obj b){
if(a.age > b.age) return 1;
if(a.age < b.age) return -1;
else return 0;
}
更新
在收到一些友好的软件工程师的解释后,我了解到比较器定义了集合中元素的顺序。例如,当比较 a 和 b 时,如果比较器 return -1 那么 a 应该放在列表中的 b 之前。
第 1 步
简化和关联此问题的一种方法可能是您的代码:
public int compare(Obj a, Obj b){
if(a.age > b.age) return 1;
if(a.age < b.age) return -1;
else return 0;
}
将表示为如下(假设 age
是 int
变量)
public int compare(Obj a, Obj b) {
return Integer.compare(a.getAge(), b.getAge());
}
其中 Integer.compare
在内部执行与之前相同的逻辑:
return (x < y) ? -1 : ((x == y) ? 0 : 1)
第 2 步
现在可以使用比较器进一步表示为:
Comparator<Obj> ageComparator = Comparator.comparingInt(Obj::getAge);
其中 Comparator.comparingInt
在内部执行
return (Comparator<T> & Serializable)
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
因此,当您调用
时,这三种形式最终产生的顺序将是相同的
objList.sort(ageComparator);
Comparable
的compareTo
方法可以在比较部分详细说明
Compares this object with the specified object for order. Returns a
negative integer, zero, or a positive integer as this object is less
than, equal to, or greater than the specified object.
因此当您覆盖 compareTo
扩展到 Comparable<Obj>
时,这被认为是 Obj
的 自然排序 。
要对一组项目进行排序,我们应该能够比较该组中的每一对项目,然后说出哪个是 "bigger",哪个是 "smaller"。
假设您的任务是手动对以下数字进行排序。
4、2、7、8、3
你会如何用你的头脑来完成这个任务?您必须查看成对的数字并进行比较,然后找出最小的数字放在开头。
类似地,为了完成排序任务,计算机需要比较成对的项目并判断哪个是 "bigger" 哪个是 "smaller"。
所以,我们写的比较器对象是"the definition"哪个大哪个小。当我们对数字进行排序时,这个定义应该说明哪个更大,哪个更小。当我们对字符串进行排序时,这个定义应该说明字母表中的哪个字母在前,哪个字母在后。
要记住的关键是比较 return 的正值 (>0) 交换是否发生。否则不会在排序算法期间。
示例:
4(a) 2(b) 6
升序排列:
a > b (4 > 2) return 1 (需要在 a 和 b 之间交换,即放置 2 4 6)
降序排列:
a > b ( 2 > 4 ) return -1 (a 和 b 之间不需要交换,即放置 4 2 6,因为它已经按顺序排列).
这个逻辑是在排序算法下实现的,所以,只要想一想如果 a 和 b 已经像你预期的那样有序,那么 return -1 否则 return 1.
我对 Java 中的比较器和 Collections.sort() 感到非常困惑。 我不明白比较器引起的顺序。我不清楚比较函数应该 return 哪个数字来获得排序方向。我也不知道 Collections 将如何使用该比较结果对输入数据进行排序。我应该记住它们吗?有什么更容易理解的吗?谁能帮我解释一下?谢谢。
public int compare(Obj a, Obj b){
if(a.age > b.age) return 1;
if(a.age < b.age) return -1;
else return 0;
}
更新
在收到一些友好的软件工程师的解释后,我了解到比较器定义了集合中元素的顺序。例如,当比较 a 和 b 时,如果比较器 return -1 那么 a 应该放在列表中的 b 之前。
第 1 步
简化和关联此问题的一种方法可能是您的代码:
public int compare(Obj a, Obj b){
if(a.age > b.age) return 1;
if(a.age < b.age) return -1;
else return 0;
}
将表示为如下(假设 age
是 int
变量)
public int compare(Obj a, Obj b) {
return Integer.compare(a.getAge(), b.getAge());
}
其中 Integer.compare
在内部执行与之前相同的逻辑:
return (x < y) ? -1 : ((x == y) ? 0 : 1)
第 2 步
现在可以使用比较器进一步表示为:
Comparator<Obj> ageComparator = Comparator.comparingInt(Obj::getAge);
其中 Comparator.comparingInt
在内部执行
return (Comparator<T> & Serializable)
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
因此,当您调用
时,这三种形式最终产生的顺序将是相同的objList.sort(ageComparator);
Comparable
的compareTo
方法可以在比较部分详细说明
Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
因此当您覆盖 compareTo
扩展到 Comparable<Obj>
时,这被认为是 Obj
的 自然排序 。
要对一组项目进行排序,我们应该能够比较该组中的每一对项目,然后说出哪个是 "bigger",哪个是 "smaller"。
假设您的任务是手动对以下数字进行排序。
4、2、7、8、3
你会如何用你的头脑来完成这个任务?您必须查看成对的数字并进行比较,然后找出最小的数字放在开头。
类似地,为了完成排序任务,计算机需要比较成对的项目并判断哪个是 "bigger" 哪个是 "smaller"。
所以,我们写的比较器对象是"the definition"哪个大哪个小。当我们对数字进行排序时,这个定义应该说明哪个更大,哪个更小。当我们对字符串进行排序时,这个定义应该说明字母表中的哪个字母在前,哪个字母在后。
要记住的关键是比较 return 的正值 (>0) 交换是否发生。否则不会在排序算法期间。
示例:
4(a) 2(b) 6
升序排列:
a > b (4 > 2) return 1 (需要在 a 和 b 之间交换,即放置 2 4 6)
降序排列:
a > b ( 2 > 4 ) return -1 (a 和 b 之间不需要交换,即放置 4 2 6,因为它已经按顺序排列).
这个逻辑是在排序算法下实现的,所以,只要想一想如果 a 和 b 已经像你预期的那样有序,那么 return -1 否则 return 1.