繁体   English   中英

Java比较器:两个排序条件

[英]Java comparator: Two ordering criteria

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

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

为了获得人员的排序列表,您将必须复制此地图的.values()作为列表,并使用Collections.sort() 如果使用番石榴,则后一部分就像Ordering.natural().sortedCopy(theMap.values())一样简单,只要您的值实现Comparable

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM