Extreme newbie here struggling to get a handle on all the different ways a list may be sorted. Suppose I have a list of objects and each object has several keys that might be used for sorting in different circumstances. I got some very useful information from this thread: Java Interface Comparator static compare, using Qwerky’s first example as a model created:
class Dog {
private String name;
private int age;
private int height;
private int weight;
Dog(String n, int a, int b, int c){
name = n;
age = a;
height = b;
weight = c;
}
public String getDogName(){
return name;
}
public int getDogAge(){
return age;
}
public int getDogHeight(){
return height;
}
public int getDogWeight(){
return weight;
}
}
class DogComparator1 implements Comparator<Dog> {
@Override
public int compare(Dog d, Dog d1){
return d.getDogAge() - d1.getDogAge();
}
}
class DogComparator2 implements Comparator<Dog> {
@Override
public int compare(Dog d, Dog d1){
return d.getDogHeight() - d1.getDogHeight();
}
}
class DogComparator3 implements Comparator<Dog> {
@Override
public int compare(Dog d, Dog d1){
return d.getDogWeight() - d1.getDogWeight();
}
}
public class Example{
public static void main(String args[]){
// Creat list of dog objects
List<Dog> dogList = new ArrayList<>();
// Add a buch of dogs to the list here
.
.
// Create the Comparators
DogComparator1 compare1 = new DogComparator1();
DogComparator2 compare2 = new DogComparator2();
DogComparator3 compare3 = new DogComparator3();
// Sort the list using Comparators
Collections.sort(list, compare1); // Sort by age
Collections.sort(list, compare2); // Sort by height
Collections.sort(list, compare3); // Sort by weight
}
}
But, this just doesn’t seem right. I think I want to pull the comparator definitions “inside” the Dog class to nicely encapsulate them. But, can’t figure out how to do it.
Am I on the right track? If so, help with the proper syntax would be greatly appreciated.
You are definitely on the right track.
I would just add this inside your Dog
class:
public static final Comparator<Dog> COMPARE_BY_AGE = new Comparator<Dog>() {
@Override
public int compare(Dog d, Dog d1) {
return d.getDogAge() - d1.getDogAge();
}
};
public static final Comparator<Dog> COMPARE_BY_HEIGHT = new Comparator<Dog>() {
@Override
public int compare(Dog d, Dog d1) {
return d.getDogHeight() - d1.getDogHeight();
}
};
public static final Comparator<Dog> COMPARE_BY_WEIGHT = new Comparator<Dog>() {
@Override
public int compare(Dog d, Dog d1) {
return d.getDogWeight() - d1.getDogWeight();
}
};
And then the usage is like follows:
// Sort the list using Comparators
Collections.sort(list, Dog.COMPARE_BY_AGE); // Sort by age
Collections.sort(list, Dog.COMPARE_BY_HEIGHT); // Sort by height
Collections.sort(list, Dog.COMPARE_BY_WEIGHT); // Sort by weight
I do not think it is a responsibility of the Dog class to know the different ways in which you can compare it. You can, however create those comparators as inner classes if that would feel more "encapsulated" for you (and even make this class private).
I.e. you could, inside Dog class, do this:
public class Dog {
(...)
public Comparator<Dog> getAgeComparator() {
return new AgeComparator();
}
private static class AgeComparator implements Comparator<Dog> {
@Override
public int compare(Dog d, Dog d1){
return d.getDogAge() - d1.getDogAge();
}
}
Or, instead of creating a getAgeComparator()
method expose those comparators as:
public static final Comparator<Dog> AGE_COMPARATOR = new AgeComparator();
You could also just create the anonymous implementation there. The way you are doing this though is correct. I would not make Dog aware of how it can be compared. You could easily have those implementations live elsewhere, or even create anonymous class implementations on the fly if you do not reuse them. What you are trying to achieve is a wrong understanding of encapsulation.
You can create a default comparator though by making Dog
class implement Comparable<Dog>
:
public class Dog implements Comparable<Dog> {
public int compareTo(Dog dog) {
return AGE_COMPARATOR.compare(this, dog); // or inline comparison here
}
(...)
}
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