Java Comparator: Two Criteria for Ordering

I have a simple class that contains a string (name) and an integer (age). Objects that should be stored in the collection should not have double names and sorted according to age. The first code example removes all double names, but does not contain second-order 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; } 

The following example comparator should sort the remaining set of objects that does not contain 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; } 

The second comparator orders the objects according to their age values ​​correctly, but it allows double names, which I don’t understand, because the external if-statement already checked if the names of both objects match. Why is this happening?

0
source share
1 answer

You have a fundamental problem: you want to check the uniqueness at the same time and order records. There is no built-in collection that will check at the same time that the entries are equal and that their comparison is 0.

For example, two implementations of Set : HashSet and TreeSet :

  • HashSet uses Object .equals() / .hashCode() to check for equality;
  • TreeSet uses Comparator (or the ability of Comparable objects, if they implement it) to check for equality.

This is not quite the same. In fact, with one specific JDK class, i.e. BigDecimal , this may seem rather unexpected:

 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 size is 2: one.equals(oneDotZero) == false treeSet.add(one); treeSet.add(oneDotZero); // treeSet size is... 1! one.compareTo(oneDotZero) == 0 

You cannot both drink and eat it. Here you want to check the uniqueness according to the name and comparison according to age, you should use Map .

To get a sorted list of faces, you will need to make a copy of this .values() map as a list and use Collections.sort() . If you use Guava, this last part is as simple as Ordering.natural().sortedCopy(theMap.values()) if your values ​​implement Comparable .

+3
source

Source: https://habr.com/ru/post/946721/


All Articles