There's a substantial distinction between the use cases for Comparator and Comparable.
Implementing the Comparable interface is suitable for objects that have a natural order in your domain model. I'm not sure whether animals have a natural order, but if it is the case from the perspective of how your application model the animals, that's fine - that's the way to go. Otherwise, your class should not implement Comparable.
It's not something opinion-based, documentation clearly defines when these interfaces are intended to be used.
Comparable:
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
compareTomethod is referred to as its natural comparison method.
Comparator:
Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps), or to provide an ordering for collections of objects that don't have a natural ordering.
Another obvious distinction, that you can define as many flavors of comparators as you need. Which is handy when there's no one specific way to compare and sort the objects. And they must have more meaningful names than comparator.
Personally, I don't see a huge harm in defining a couple of comparators as public static final fields, as in your example. If you have a single class that manages the instances of this type - extract the comparators into that class, otherwise if these objects are ubiquitous and used in many places you can leave them right inside the POJO (that an opinion based part).
java - When should I use Comparator vs Comparable? - Stack Overflow
Comparator vs Comparable
Comparator vs Comparable
6 Advanced Comparator and Comparable Examples in Java 8 for Sorting ArrayList Objects By Fields
In regards to comparable vs comparator, what is a comparator?
In regards to comparable vs comparator, what is comparable?
What is the main difference between comparable vs comparator?
Videos
There's a substantial distinction between the use cases for Comparator and Comparable.
Implementing the Comparable interface is suitable for objects that have a natural order in your domain model. I'm not sure whether animals have a natural order, but if it is the case from the perspective of how your application model the animals, that's fine - that's the way to go. Otherwise, your class should not implement Comparable.
It's not something opinion-based, documentation clearly defines when these interfaces are intended to be used.
Comparable:
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
compareTomethod is referred to as its natural comparison method.
Comparator:
Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps), or to provide an ordering for collections of objects that don't have a natural ordering.
Another obvious distinction, that you can define as many flavors of comparators as you need. Which is handy when there's no one specific way to compare and sort the objects. And they must have more meaningful names than comparator.
Personally, I don't see a huge harm in defining a couple of comparators as public static final fields, as in your example. If you have a single class that manages the instances of this type - extract the comparators into that class, otherwise if these objects are ubiquitous and used in many places you can leave them right inside the POJO (that an opinion based part).
This is not opinion based: TL;DR implement Comparable:
semantically, this is what Interfaces are designed for: they express a contract enforced by an object, a behavior of the object: if the objects are serializable, then they should implement
Serializable, if they are comparable, then they should implementComparable, etc...inheritance will work as expected and be more readable: if you define a
Dogthat extendsAnimal, you can implement comparison forDogusing the super implementation (i.e. a Dog is compared like any otherAnimal) or overriding the implementation to implement a behavior specific toDog. The user of yourDogclass simply callsinstance.compareTo(...)without having to worry about what final static comparator she/he should callusers of your
AnimalAPI know they have to implementComparablewhen adding their own animal to the inheritance tree