Java比较器:两个排序标准 [英] Java comparator: Two ordering criteria

查看:134
本文介绍了Java比较器:两个排序标准的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a simple class that contains a string (name) and an integer (age). The objects, that shall be stored in the collection, must not have double name values and shall be sorted according to descending age. The first code example removes all double names, but doesn't contain a second ordering criterion:

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

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

下一个示例比较器应命令对象的其余集合, t包含任何双重名称:

The next example comparator shall order the rest set of the objects, that doesn't contain any double names:

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语句已经检查了两个对象的名称是否相等。为什么会发生这种情况?

The second comparator orders the objects according their age values correctly, but it allows double names, which I don't understand, because the outer if-statement already checked if the names of both objects are equal. Why does that happen?

推荐答案

这里有一个根本的问题:你想同时测试unicity 来订购条目。没有内置集合,它将同时检查条目等于,它们的比较为0.

You have a fundamental problem here: you want at the same time to test for unicity and to order entries. There is no builtin collection which will check at the same time that entries are equal and that their comparison is 0.

例如,两个设置实现 HashSet TreeSet


  • HashSet 使用对象 .equals() / .hashCode()测试平等性;

  • code> TreeSet 使用 Comparator (或对象的 Comparable 他们实现它)测试平等。

  • HashSet uses Object's .equals()/.hashCode() to test for equality;
  • TreeSet uses a Comparator (or the objects' Comparable capability if they implement it) to test for equality.

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

This is not quite the same thing. In fact, with one particular JDK class, that is, BigDecimal, this can get quite surprising:

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

你不能同时拥有你的蛋糕和吃它。在这里,你想根据名字测试unicity,并根据年龄进行比较,你必须使用 Map

You cannot both have your cake and eat it. Here, you want to test unicity according to the name and comparison according to the age, you must use a Map.

为了获得排序的人员列表,您必须将此地图的 .values()复制为列表,并使用集合.sort()。如果你使用Guava,后面的部分就像 Ordering.natural()。sortedCopy(theMap.values()),只要你的值实现比较

As to obtain a sorted list of persons, you will have to do a copy of this map's .values() as a list and use Collections.sort(). If you use Guava, this latter part is as simple as Ordering.natural().sortedCopy(theMap.values()), provided your values implement Comparable.

这篇关于Java比较器:两个排序标准的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆