I was thinking of implementing multiple Comperators. Now I am not sure about how to do this in a most favourable way, i.e. still having the ability to do dependency injection.
Method 1: One class is one comparator (as seen in this answer):
// file LexicographicComparator.java
class LexicographicComparator implements Comparator<Person> {
@Override
public int compare(Person a, Person b) {
return a.name.compareToIgnoreCase(b.name);
}
}
// file AgeComparator.java
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person a, Person b) {
return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
}
}
Method 2: Now it would surely be possible to do sth like this:
class PersonComperatorFactory {
public static Comparator<Person> getAgeComparator() {
return new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
}
}
}
public static Comparator<Person> getLexicographicComparator() {
return new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return a.name.compareToIgnoreCase(b.name);
}
}
}
}
The second method is surely less cluttering your packages (put it to the .domain package or .util package? Or create a new .domain.comperators package?). But is this a good idea at all? I mean, does this have any benefits besides less files? What about code reusage, or DependencyInjection - may it have drawbacks I am yet unable to see?
I'd like this to be not a "chose your favourite"-question, but there may be many good reasons why to use one or the other.
Thank you very much in advance.
PS: In which package would you put this (this is probably a personal choice)? But this is only a side-question suitable for a comment.
In my opinion the best way to achieve the desidered result is to have an utility class (putting it in .util package) containing all your static comparators.
Example:
public class Comparators {
public static final Comparator<Person> PERSON_LEXICOGRAPHIC_COMPARATOR = new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return a.name.compareToIgnoreCase(b.name);
}
}
public static final Comparator<Person> PERSON_AGE_COMPARATOR = new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
}
}
}
Or in the Java 8 way:
public class Comparators {
public static final Comparator<Person> PERSON_LEXICOGRAPHIC_COMPARATOR = (Person a, Person b) -> a.name.compareToIgnoreCase(b.name);
public static final Comparator<Person> PERSON_AGE_COMPARATOR = (Person a, Person b) -> (a.age < b.age ? -1 : a.age == b.age ? 0 : 1);
}
I would use directly the static instances in order to do not waste memory and resources, since they do not use any state attribute in the compare method.
IMHO the best way is a mix because you have a single entry point to get all your comparators (you don't need to know name of each comparator: all are in the same java class) and you can instantiate all your comparators as a bean.
public class LexicographicComparator implements Comparator<Person> {
@Override
public int compare(Person a, Person b) {
return a.name.compareToIgnoreCase(b.name);
}
}
// file AgeComparator.java
public class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person a, Person b) {
return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
}
}
public class PersonComperatorFactory {
private static final Comparator<Person> NAME_COMPARATOR = new LexicographicComparator();
private static final Comparator<Person> AGE_COMPARATOR = new AgeComparator();
public static Comparator<Person> getLexicographicComparator() {
return NAME_COMPARATOR;
}
public static Comparator<Person> getAgeComparator() {
return AGE_COMPARATOR;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With