Search code examples
javasortingcollectionsrx-javaguava

Sorting a list of lists in an specific order


This question is about sorting lists.

I have a generic method to get Vehicles

List<Vehicle>  getRandomVehiclesList() {    
   return  fetchVehicles(); 
   //returns List <Car>, List<Bus>, etc
   };

Vehicles can be Car, Motorcycle, Bus, Truck, SUV, etc.

Car extends Vehicle
Bus extends Vehicle

Say I want to call 5 times getRandomVehiclesList() and then sort the resulted 5 lists in an specific order.

—————————————————————————————————

THE LIST NEEDS TO BE IN THIS ORDER

List<Car>
List<Truck>
List<SUV>
List<Bus>
List<Motorcycle>

—————————————————————————————————

but the results can be returned in this order or other random order.

List<Bus>
List<Motorcycle>
List<Truck>
List<Car>
List<SUV>

What is the best way to sort all the lists so they match the order shown above (Car,Truck,Suv,Bus,Motorcycle)

Can RxJava be used to simplify?


Solution

  • You can easily create your own Comparator<List<Vehicle>> taking advantage of Guava's Ordering.explicit comparator:

    class VehicleListComparator implements Comparator<List<Vehicle>> {
        private final Ordering<Class<? extends Vehicle>> vehicleClassOrdering;
    
        public VehicleListComparator(Ordering<Class<? extends Vehicle>> vehicleClassOrdering) {
            this.vehicleClassOrdering = vehicleClassOrdering;
        }
    
        @Override
        public int compare(List<Vehicle> vehiclesList1, List<Vehicle> vehiclesList2) {
            Class<? extends Vehicle> left = getVehicleClass(vehiclesList1);
            Class<? extends Vehicle> right = getVehicleClass(vehiclesList2);
            return vehicleClassOrdering.compare(left, right);
        }
    
        private Class<? extends Vehicle> getVehicleClass(List<Vehicle> vehicleList) {
            if (vehicleList.isEmpty()) {
                throw new IllegalArgumentException();
            } else {
                return vehicleList.get(0).getClass();
            }
        }
    }
    

    You can then sort your list of vehicle lists using this comparator:

    Ordering<Class<? extends Vehicle>> vehicleClassOrdering = Ordering.explicit(Arrays.asList(
            Car.class, Truck.class, SUV.class, Bus.class, Motorcycle.class));
    Collections.sort(vehicleLists, new VehicleListComparator(vehicleClassOrdering));