Java comparator: Two ordering criteria

点点圈 提交于 2019-11-29 17:47:51

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.

For instance, two Set implementations are HashSet and TreeSet:

  • 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.

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

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!