gpt4 book ai didi

Java比较器: Two ordering criteria

转载 作者:行者123 更新时间:2023-12-01 23:46:31 25 4
gpt4 key购买 nike

我有一个简单的类,其中包含一个字符串(名称)和一个整数(年龄)。应存储在集合中的对象不得具有双重名称值,并应根据年龄降序排序。第一个代码示例删除所有双重名称,但不包含第二个排序标准:

public int compare(Person p1, Person p2) {  
int reVal = 1;

if(p1.getName().compareTo(p2.getName()) != 0){
reVal = 1;
}
else {
reVal = 0;
}
return reVal;
}

下一个示例比较器将对其余对象集进行排序,其中不包含任何双重名称:

public int compare(Person p1, Person p2) {  
boolean ageGt = (p1.getAge() > p2.getAge());
int reVal = 1;

if(p1.getName().compareTo(p2.getName()) != 0){
if(scoreGt)
reVal = -1;
else
reVal = 1;
}
else {
reVal = 0;
}
return reVal;
}

第二个比较器根据对象的年龄值正确地对对象进行排序,但它允许双重名称,我不明白,因为外部 if 语句已经检查了两个对象的名称是否相等。为什么会发生这种情况?

最佳答案

这里有一个根本问题:您想要同时测试唯一性来排序条目。没有内置集合会同时检查条目是否相等以及它们的比较是否为 0。

例如,两个 Set 实现是 HashSetTreeSet:

  • HashSet 使用 Object.equals()/.hashCode() 来测试相等性;
  • TreeSet 使用 Comparator(或对象的 Comparable 功能,如果它们实现了的话)来测试相等性。

这不完全是一回事。事实上,对于一个特定的 JDK 类,即 BigDecimal,这可能会让人非常惊讶:

final BigDecimal one = new BigDecimal("1");
final BigDecimal oneDotZero = new BigDecimal("1.0");

final Set<BigDecimal> hashSet = new HashSet<>();
// BigDecimal implements Comparable of itself, so we can use that
final Set<BigDecimal> treeSet = new TreeSet<>();

hashSet.add(one);
hashSet.add(oneDotZero);
// hashSet's size is 2: one.equals(oneDotZero) == false

treeSet.add(one);
treeSet.add(oneDotZero);
// treeSet's size is... 1! one.compareTo(oneDotZero) == 0

鱼与熊掌不可兼得。这里,想要根据名字测试唯一性,根据年龄比较,就必须使用一个Map

要获取已排序的人员列表,您必须将此 map 的 .values() 复制为列表并使用 Collections.sort() 。如果您使用 Guava,则后一部分就像 Ordering.natural().sortedCopy(theMap.values()) 一样简单,前提是您的值实现 Comparable

关于Java比较器: Two ordering criteria,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16959072/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com