Choosing between Comparator and Comparable

To implement sorting, it is required that the objects being sorted can be compared with each other for more or less. In other words, to define a rule that will allow for any two objects to indicate which of them within the given context comes earlier and which later.

In java, these rules are defined at the level of the classes to which the objects belong. For example, let's take a class for describing a user's account:

UserAccount {
  currency
  value
  updatedTimestamp
}

Depending on the context, user accounts can be compared according to different rules, for example:

  • in the application, the user sees accounts sorted by currency, then by value;

  • in the admin panel, all user accounts are sorted by modification date.

To implement comparison for more or less in java, there are two possibilities:

  • UserAccount implements the interface Comparable<UserAccount>In this case, two objects get the ability to compare with each other:acc1.compareTo(acc2)

  • A separate class is created that implements the interface Comparator<UserAccount>, and then the object of this class can compare two objects of the original class with each other:userAccountComparator.compare(acc1, acc2)

Obviously, in some cases, there is no choice between Comparable and Comparator. If the original class cannot be modified, or if different comparison rules are required, then a Comparator must be used. Otherwise, you can technically use both Comparator and Comparable.

Comparable , (class's natural ordering). , (String, Date). , . , . ( BigDecimal , 4.0 4.00?). , "" . Comparable.

. , . . : . :

  • : Arrays.sort(accountsList)

  • : Arrays.sort(accountsList, accountByValueComparator)

, compareTo UserAccount, - accountByValueComparator. . .

UserAccount implements Comparable<UserAccount> {
  @Override
  public int compareTo(UserAccount other) { .. }
}

, compareTo ? , Comparable#compareTo, Arrays.sort(). jdk, . : UserAccount Arrays.sort(), stream.sorted() .

In the case of an explicit transfer of a comparator, finding its use is elementary. I take this as an argument for using a comparator. (Equals / hashCode is another example of difficulty finding implicit usages, but there is no "Equalator" alternative for them).

In summary, in most cases, the arguments for using Comparator outweigh the arguments for using Comparable.




All Articles