Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
155 views
in Technique[技术] by (71.8m points)

java - Create a generic comparator when classes are not related to each other but have a common property on which sorting is required

I want to create a custom comparator in java that can take different types of classes and sort by a particular method (which will be the same across all the classes). These classes are not related to each other and inheritance can't be applied to them.

For instance, suppose I have 2 classes Car and Bike, and both of them have a getter method which gives the count of how many of that particular vehicle has been sold. Now I want to sort a list of the particular vehicle based on this parameter.

public class Car {



private int selledUnits;

...



public int getSelledUnits() {

    return selledUnits;

  }

}



public class Bike {

private int selledUnits;

...



public int getSelledUnits() {

    return selledUnits;

  }

  ...

}

Now, suppose I have List<Car> cars and List<Bike> bikes and I want to sort these cars based on selledUnits field.

Currently, I am sorting by creating different comparators for a different class .

For example, for Car, I have created below comparator for sorting

class CarComparator implements Comparator<Car> {

public int compare(Car c1, Car c2) {

return c1.selledUnits - c2.selledUnits;

}

}

Similarly for sorting list of bikes below comparator is used :

class BikeComparator implements Comparator<Bike> {

public int compare(Bike b1, Bike b2) {

return b1.selledUnits - b2.selledUnits;

}

}

My question is instead of creating a separate comparator for each of these classes can I create a generic comparator, since both of them are sorting based on the same fields.

I have tried creating a generic comparator by using reflection and it is working fine but wanted to create the same without using reflection.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is an example how you could achieve it using a wrapper:

class NotVehicleException extends  RuntimeException {}

class VehicleWrapper{

    Object wrappedVehicle;

    public VehicleWrapper(Car wrappedVehicle) {
        this.wrappedVehicle = wrappedVehicle;
    }

    public VehicleWrapper(Bike wrappedVehicle) {
        this.wrappedVehicle = wrappedVehicle;
    }

    public int getSelledUnits() {
            if(wrappedVehicle instanceof Car)
                return ((Car) wrappedVehicle).getSelledUnits(); 
            else if ( wrappedVehicle instanceof Bike) 
                return ((Bike) wrappedVehicle).getSelledUnits();
            else throw new NotVehicleException();
        }
    }

class VehicleComparator implements Comparator<VehicleWrapper>{
    public int compare(VehicleWrapper b1, VehicleWrapper b2) {

        return b1.getSelledUnits() - b2.getSelledUnits();

    }

}

Of course, this won't give you the flexibility and elegance which you would achieve having a common class or interface, so every time you add another Vehicle type - you'll have to update the wrapper. But in general, wrappers are a common solution to bind the unbound.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...