2

In Java, when should I implement Comparable<Something> versus implementing the equals method? I understand every time I implement equals I also have to implement hash code.

EDIT

Based on answers I am getting below:

Is it safe to say that if I implement Comparable then I don't need to implement equals and hashCode? As in: whatever I can accomplish with equal is already included in compareTo? For an example, I want to be able to compare two BSTs for equality. Implementing a hashCode for that seems daunting; so would comparable be sufficient?

2
  • if you want sorted collection then you can go with comparable, in rest case equals. Commented Apr 29, 2015 at 16:02
  • you will get better explanation in effective java by joshua bloch Item 12 Commented Apr 29, 2015 at 16:08

6 Answers 6

3

If you only ever need to compare them for equality (or put them in a HashMap or HashSet which is effectively the same) you only need to implement equals and hashcode.

If your objects have an implicit order and you indend to sort them (or put them in a TreeMap or TreeSet which is effectively sorting) then you must implement Comparable or provide a Comparator.

Sign up to request clarification or add additional context in comments.

1 Comment

then you must implement Comparable. Not necessarily. You can implement Comparable or Comparator. The "must" makes it sound like that's the only option.
2

Comparable is typically used for ordering items (like sorting) and equals is used for checking if two items are equal. You could use comparable to check for equality but it doesn't have to be. From the docs, "It is strongly recommended (though not required) that natural orderings be consistent with equals"

Comments

2

equals (and hashCode) are used for equality tests. The Comparable interface can be used for equality checks too, but it is in practice used for sorting elements or comparing their order.

That is, equals deals only with equality (similar to == and !=), while compareTo allows you to check many different types of inequality (similar to <, <=, ==, >=, > and !=). Therefore, if your class has a partial or total ordering of some kind, you may want to implement Comparable.

The relationship between compareTo and equals is briefly mentioned in the javadocs for Comparable:

It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."

Comparable is used by TreeSet to compare and sort anything you insert into it, and it is used by List#sort(null) to sort a list. It will be used in other places too, but those are the first that come to mind.

2 Comments

Do you know whether comparable is used by HashSet and HashMap? Or must I implement equals and hashCode for those?
HashSet and HashMap use hashCode to get an approximate idea of where to do their lookup, and equals to complete the lookup. So you must implement both of these, and they must be consistent with each other.
1

You should consider when you will use the object. If for example in TreeMap and TreeSet, then you'll need Comparable. Also any case, when you will have to sort elements(especially sorted collections), implementing Comparable is mandatory. Overriding equals and hashcode will be needed in a very large amount of cases, most of them.

Comments

1

As per the javadocs:

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method. Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections.sort (and Arrays.sort). Objects that implement this interface can be used as keys in a sorted map or as elements in a sorted set, without the need to specify a comparator.

The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false

In short, equals() and hashcode() are for comparing equality whereas Comparable is for sorting

Comments

1

If you update the equals method, you should always update hashCode or you will be setting a boobytrap for yourself or others when they try to use it in a HashMap or HasSet or similar collections (very commonly used).

Comparable is required only when the interfaces you are working with require it. You can implement it for use with sorting and sorted collections but it's not actually required in most cases. An alternate approach is to pass in a Comparator to the sort or collection constructor. For example the String class has a case insensitive Comparator that is very useful and eliminates the need to create your own String class (i.e. String cannot be extended.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.