Java比较器:两个排序条件
我有一个简单的类,其中包含一个字符串(名称)和一个整数(年龄)。应存储在集合中的对象不得具有双名值,并且应根据年龄的降序进行排序。第一个代码示例删除所有双精度名称,但不包含第二个排序条件:
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
实现是HashSet
和TreeSet
:
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
。
为了获得人员的排序列表,您将必须复制此地图.values()
作为列表并使用Collections.sort()
。如果您使用Guava,则后一部分将很简单Ordering.natural().sortedCopy(theMap.values())
,前提是您的值实现了Comparable
。
以上是 Java比较器:两个排序条件 的全部内容, 来源链接: utcz.com/qa/409773.html