我有一个包含字符串(名称)和整数(年龄)的简单类。应存储在集合中的对象不得具有双重名称值,并应根据年龄下降进行排序。 第一个代码示例删除所有双重名称,但不包含第二个排序标准:
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 :(得分:3)
这里有一个根本问题:您希望同时测试unicity 和以订购条目。没有内置集合可以同时检查条目和,它们的比较为0。
例如,两个Set
实施是HashSet
和TreeSet
:
HashSet
使用Object
的{{1}} / .equals()
来测试相等性; .hashCode()
使用TreeSet
(或对象'Comparator
功能实现它)来测试是否相等。这不是一回事。事实上,对于一个特定的JDK类,即Comparable
,这可能会非常令人惊讶:
BigDecimal
你不能同时吃蛋糕而且吃它。在这里,您想根据年龄根据名称和比较来测试unicity,您必须使用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()
。如果您使用Guava,后一部分就像Collections.sort()
一样简单,只要您的值实现Ordering.natural().sortedCopy(theMap.values())
。