This is a very good question.
The natural ordering for a class C is said to be consistent with equals if and only if (e1.compareTo((Object)e2) == 0) has the same boolean value as e1.equals((Object)e2) for every e1 and e2 of class C.
In your first c1.equals(c2) = false but c1.compareTo(c2) = true. Hence your implementation of Comparable is
inconsistent because compareTo() and equals() are not consistent.
It is strongly recommended (though not required) that natural orderings be consistent with equals. This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method.
For example, if one adds two keys a and b such that (!a.equals((Object)b) && a.compareTo((Object)b) == 0) to a sorted set that does not use an explicit comparator, the second add operation returns false (and the size of the sorted set does not increase) because a and b are equivalent from the sorted set's perspective.
Virtually all
Java core classes that implement comparable have natural orderings that are consistent with equals.
In your first code you are aware that c1 and c2 are two different objects and when added to set must be added but because compareTo() and equals() are not consistentlt implemented, the second Cat object is not added to Set.
Hence the second implementation is correct.