1

I am trying to develop a program that can sort an array of objects that are of different class types, but in the same hierarchy as one another. All of the objects are listed within the same array that I am trying to sort, and while I can alphabetically sort an array of objects that are of the same type easily enough, I cannot figure out how to sort everything all at once with the same Arrays.sort() method. Any help that anyone could provide would be greatly appreciated.

import java.util.Arrays;

public class Driver {

public static void main(String[] args) {

    Vehicle[] machines = new Vehicle[3];//Example of an array that I can sort
    machines[0] = new Vehicle("Giant Robot");
    machines[1] = new Vehicle("Time Machine");
    machines[2] = new Vehicle("Airplane");
    Arrays.sort(machines);
    for (int i = 0; i < machines.length; i++)
        System.out.println(machines[i].getName());


    Vehicle[] vehicles = new Vehicle[7];//example of an array that I cannot sort
    vehicles[0] = new Car("Batmobile", 10);
    vehicles[1] = new Helicopter("Batcopter", "x");
    vehicles[2] = new Car("Jaguar", 6);
    vehicles[3] = new Helicopter("RC Copter", "t");
    vehicles[4] = new Car("Accelerator", 6);
    vehicles[5] = new Helicopter("Stormshadow", "z");
    vehicles[6] = new Car("Batmobile", 11);
}

}

**

public class Vehicle implements Comparable {
private String name;

public Vehicle(){
    name = "no name";
}

public Vehicle(String newName){
    name = newName;
}

public String getName(){
    return name;
}

public int compareTo(Object o)
{
    if ((o != null) &&
        (o instanceof Vehicle))
    {
        Vehicle otherVehicle = (Vehicle) o;
        return (name.compareTo(otherVehicle.name));
    }
    return -1;
}

}

**

public class Car extends Vehicle {

private int tireSize;

public Car(){
    super();
    tireSize = 0;
}

public Car(String newName, int newTireSize){
    super(newName);
    tireSize = newTireSize;
}

public int getSize(){
    return tireSize;
}

}

**

public class Helicopter extends Vehicle {

private String bladeType;

public Helicopter(){
    super();
    bladeType = "none";
}

public Helicopter(String newName, String newBlade){
    super(newName);
    bladeType = newBlade;
}

public String getType(){
    return bladeType;
}

}
5
  • 1
    Why are you implementing Comparable rather than Comparable<? extends Vehicle>? Commented Mar 20, 2016 at 23:03
  • @Tom It would be nice, if you could accept/upvote an answer if your issue is resolved. From here, "Accepting an answer is important as it both rewards posters for solving your problem and informs others that your issue is resolved." Commented Mar 20, 2016 at 23:58
  • 2
    My issue has not been resolved yet, but I will up vote an answer as soon as I get my code working(which will hopefully be soon). Commented Mar 21, 2016 at 0:34
  • @Tom, it's kinda hard to figure out what problem you're having, so you have a bunch of answers with different guesses about that. You may want to explain why each of those doesn't satisfy. My guess is different -- I think you want to know about a pattern called "double dispatch": en.wikipedia.org/wiki/Double_dispatch Commented Mar 21, 2016 at 5:16
  • brushed up against this myself. Any solution found yet? Commented Aug 31, 2016 at 0:45

4 Answers 4

1

Goal: You need to be able to compare a Vehicle to other of Vehicle.

To achieve that goal:

public class Vehicle implements Comparable<? extends Vehicle> {

    ....

    public int compareTo(Object o) {
        // Now, that the Comparable is for the type Vehicle
        // you know that o is some kind of vehicle

        // check vehicle related things
        // number of seats, dogs, whatever
        return -1;
    }

}
Sign up to request clarification or add additional context in comments.

Comments

1

You just need to adjust your code to:

class Vehicle implements Comparable<Vehicle> {

    private String name;

    /* ... */

    @Override
    public int compareTo(Vehicle vehicle) {
        return name.compareTo(vehicle.getName());
    }
}

Comments

0

In most cases, your classes should not implement Comparable, unless there is one and only one ordering that is always the correct one, like with numbers. Your vehicles can be sorted by name, by age, and probably by more criteria, so they should not implement Comparable.

Instead, you can pass the ordering function as a lambda function, at the time where you actually sort your vehicles:

Arrays.sort(machines, (left, right) -> left.getName().compareTo(right.getName()));

Or, equivalently:

Arrays.sort(machines, Comparator.comparing(Vehicle::getName));

This way you don’t need the implements Comparable anymore.

Comments

-1

If you want to sort by vehicle type then you need to take class type into consideration, while sorting the element. Modify the compareTo() method as shown below:

public int compareTo(Object o){
    if ((o != null) &&
        (o instanceof Vehicle)){
        Vehicle otherVehicle = (Vehicle) o;
        return (otherVehicle.getClass().getSimpleName().equals(this.getClass().getSimpleName()) ? 
                name.compareTo(otherVehicle.name) 
                : otherVehicle.getClass().getSimpleName().compareTo(this.getClass().getSimpleName()));
    }
    return -1;
}

1 Comment

The o != null is redundant, since instanceof checks for null. • The getSimpleName methods should only be called once per object, both for performance and readability. • Returning -1 by default is wrong, since it typically prevents compareTo from being antisymmetrical. • The parameter type should be Vehicle instead of Object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.