Comparable vs. Comparator

Published Jun 07, 2017

You should favor the Comparator-interface over the Comparable-interface.

Comparision of two objects is always context specific. If you implement the Comparable-interface your class is bound to the context you defined. If you change the comparison you have to check every single usage semantically to ensure no side effects.

I prefer using the Comparator-interface to define context specific comparison without taking the burden on the class to compare. If I want to provide one or more natural order comparators I provide them to the class under comparison as public constants.


public class ComparatorExample {

  public static void main(String[] args) {

    List<SomeObject> list = new ArrayList<>();

    list.add(new SomeObject(1, "dhjf", "A"));
    list.add(new SomeObject(4, "ghdg", "A"));
    list.add(new SomeObject(6, "uztzt", "B"));
    list.add(new SomeObject(1, "jhgf", "C"));
    list.add(new SomeObject(3, "vbbn", "A"));
    list.add(new SomeObject(99, "cvcxc", "A"));
    list.add(new SomeObject(2, "dfdd", "G"));

    // examples
    Collections.sort(list, SomeObject.NATURAL);
    Collections.sort(list, LexicographicOrderByCategoryAndName.INSTANCE); SomeObject(99, "cvcxc", "A"), new SomeObject(54, "fdjnn", "C"));

  public static class SomeObject {
    public static Comparator<SomeObject> NATURAL = new Comparator<SomeObject>() {

      public int compare(SomeObject arg0, SomeObject arg1) {
        return arg1.getId() - arg0.getId();
    private int id;
    private String name;
    private String category;
    public SomeObject(int id, String name, String category) { = id; = name;
      this.category = category;
    public int getId() {
      return id;
    public String getName() {
      return name;
    public String getCategory() {
      return category;
  public static class LexicographicOrderByName implements Comparator<SomeObject> {

    public static LexicographicOrderByName INSTANCE = new LexicographicOrderByName();
    private LexicographicOrderByName() {
    public int compare(SomeObject o1, SomeObject o2) {
      return o1.getName().compareTo(o2.getName());

  public static class LexicographicOrderByCategoryAndName implements Comparator<SomeObject> {

    public static LexicographicOrderByCategoryAndName INSTANCE = new LexicographicOrderByCategoryAndName();

    private LexicographicOrderByCategoryAndName() {
    public int compare(SomeObject o1, SomeObject o2) {
      int c = o1.getCategory().compareTo(o2.getCategory());
      if (c == 0) {
        c = o1.getName().compareTo(o2.getName());
      return c;
Discover and read more posts from Arne Lewinski
get started