Using a comparator to sort 2 separate instances

Standard

Consider you have 2 separate classes; “dog” and “cat”. Both of these classes share a common interest in that they are animals. Each of these animals have a date of birth. In this example I will demonstrate how to merge 2 object arrays of both types (“dog” and “cat”) and sort them by their common property; date of birth.

Where might I need this?

In the case of needing both cats and dogs on the same dataTable in JSF this would provide a merged object array to iterate through.

The Code

Creating the abstract class “animal” to be extended by both the dog and cat classes. This abstract class defines what both a cat and dog have in common; a name.

public abstract class Animal {

    /**
     * All animals must have a name
     */
    protected String name;

    public abstract String getName();

    public abstract void setName(String name);

}

Both the cat and dog classes are very similar. For the purpose of this tutorial they both only have a date of birth.

public class Cat extends Animal {

    private Date dob;

    public Cat(String name, Date dob) {
        setDob(dob);
        setName(name);
    }

    public Date getDob() {
        return this.dob;
    }

    public void setDob(Date date) {
        this.dob = date;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

}

The dog class is identical to the cat class.

public class Dog extends Animal {

    private Date dob;

    public Dog(String name, Date date) {
        setDob(date);
        setName(name);
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    public Date getDob() {
        return this.dob;
    }

    public void setDob(Date date) {
        this.dob = date;
    }

}

The Solution

To sort both cats and dogs by date of birth first begin by creating a list of each type then adding a few objects to each. The code below adds 2 animals to each type. Then all objects are added to a list of object array. Using collection.sort comparator it checks which type of object is being passed. It then casts that object to its instance type and gets the date of birth. The final statement in the method is the compareTo function which compares the date of birth for each type. Using this approach you can see that you could easily add additional object array types and sort them all by a common date.

 List <Cat> cats = new ArrayList <> ();
 cats.add(new Cat("Chester", new Date(105, 9, 4)));
 cats.add(new Cat("Peaches", new Date(105, 8, 1)));

 List <Dog> dogs = new ArrayList <> ();
 dogs.add(new Dog("Willie", new Date(115, 2, 4)));
 dogs.add(new Dog("Buster", new Date(89, 3, 4)));

 List <Object> objects = new ArrayList <> ();

 objects.addAll(cats);
 objects.addAll(dogs);

 Collections.sort(objects, new Comparator <Object> () {@
     Override
     public int compare(Object m1, Object m2) {
         Date d1 = null;
         Date d2 = null;

         if (m1 instanceof Cat) {
             d1 = ((Cat) m1).getDob();
         } else {
             d1 = ((Dog) m1).getDob();
         }

         if (m2 instanceof Cat) {
             d2 = ((Cat) m2).getDob();
         } else {
             d2 = ((Dog) m2).getDob();
         }

         return d1.compareTo(d2);
     }
 });

 for (Object o: objects) {
     if (o instanceof Cat) {
         System.out.println("Name: " + ((Animal) o).getName() + " DOB: " + ((Cat) o).getDob());
     } else {
         System.out.println("Name: " + ((Animal) o).getName() + " DOB: " + ((Dog) o).getDob());
     }
 }

The following code is available on Github.