首页 > 解决方案 > 当类彼此不相关但具有需要排序的公共属性时创建通用比较器

问题描述

我想在 java 中创建一个自定义比较器,它可以采用不同类型的类并按特定方法排序(所有类都相同)。这些类彼此不相关,不能对它们应用继承。

例如,假设我有 2 个类 Car 和 Bike,它们都有一个 getter 方法,用于计算该特定车辆已售出的数量。现在我想根据这个参数对特定车辆的列表进行排序。

public class Car {



private int selledUnits;

...



public int getSelledUnits() {

    return selledUnits;

  }

}



public class Bike {

private int selledUnits;

...



public int getSelledUnits() {

    return selledUnits;

  }

  ...

}

现在,假设我有List<Car> cars并且List<Bike> bikes我想根据selledUnits字段对这些汽车进行分类。

目前,我正在通过为不同的类创建不同的比较器进行排序。

例如,对于 Car,我在下面创建了用于排序的比较器

class CarComparator implements Comparator<Car> {

public int compare(Car c1, Car c2) {

return c1.selledUnits - c2.selledUnits;

}

}

类似地,使用比较器下面的自行车排序列表:

class BikeComparator implements Comparator<Bike> {

public int compare(Bike b1, Bike b2) {

return b1.selledUnits - b2.selledUnits;

}

}

我的问题是,我可以创建一个通用比较器,而不是为这些类中的每一个创建一个单独的比较器,因为它们都是基于相同的字段进行排序的。

我尝试使用反射创建一个通用比较器,它工作正常,但想在不使用反射的情况下创建相同的比较器。

标签: javagenerics

解决方案


这是一个如何使用包装器实现它的示例:

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();

    }

}

当然,这不会为您提供拥有通用类或接口所获得的灵活性和优雅性,因此每次添加另一种车辆类型时 - 您都必须更新包装器。但总的来说,包装器是绑定未绑定的常用解决方案。


推荐阅读