¿Cómo uso Comparator para definir un orden de clasificación personalizado?

Resuelto akhtar asked hace 13 años • 0 respuestas

Quiero desarrollar una demostración de clasificación para la lista de automóviles. Estoy usando la tabla de datos para mostrar la lista de autos. Ahora quiero ordenar la lista por color de coche. Aquí no está ordenado por orden alfabético. Quiero usar mi orden de clasificación personalizado, como el auto rojo primero, luego el azul, etc.

Para eso trato de usar Java Comparatory Comparablesolo permite ordenar en orden alfabético.

Entonces, ¿alguien puede guiarme sobre la forma de implementar la técnica a utilizar para que la clasificación sea más rápida?

class Car implements Comparable<Car>
{
    private String name;
    private String color;

    public Car(String name, String color){
        this.name = name;
        this.color = color;
    }

    //Implement the natural order for this class
    public int compareTo(Car c) {
        return name.compareTo(c.name);
    }

    static class ColorComparator implements Comparator<Car> {
        public int compare(Car c1, Car c2) {
            String a1 = c1.color;
            String a2 = c2.color;
            return a1.compareTo(a2);
        }
    }

    public static void main(String[] args) {
        List<Car> carList = new ArrayList<>();
        List<String> sortOrder = new ArrayList<>();

        carList.add(new Car("Ford","Silver"));
        carList.add(new Car("Tes","Blue"));
        carList.add(new Car("Honda","Magenta"));

        sortOrder.add("Silver");
        sortOrder.add("Magenta");
        sortOrder.add("Blue");

        // Now here I am confuse how to implement my custom sort             
    }
}
akhtar avatar Mar 09 '11 18:03 akhtar
Aceptado

Le recomiendo que cree una enumeración para los colores de su automóvil en lugar de usar cadenas y el orden natural de la enumeración será el orden en el que declare las constantes.

public enum PaintColors {
    SILVER, BLUE, MAGENTA, RED
}

y

 static class ColorComparator implements Comparator<CarSort>
 {
     public int compare(CarSort c1, CarSort c2)
     {
         return c1.getColor().compareTo(c2.getColor());
     }
 }

Cambia la cadena a PaintColor y luego, en la lista principal, su lista de automóviles se convierte en:

carList.add(new CarSort("Ford Figo",PaintColor.SILVER));

...

Collections.sort(carList, new ColorComparator());
z7sg Ѫ avatar Mar 09 '2011 11:03 z7sg Ѫ

Qué tal esto:

List<String> definedOrder = // define your custom order
    Arrays.asList("Red", "Green", "Magenta", "Silver");

Comparator<Car> comparator = new Comparator<Car>(){

    @Override
    public int compare(final Car o1, final Car o2){
        // let your comparator look up your car's color in the custom order
        return Integer.valueOf(
            definedOrder.indexOf(o1.getColor()))
            .compareTo(
                Integer.valueOf(
                    definedOrder.indexOf(o2.getColor())));
    }
};

En principio, estoy de acuerdo en que usar un enumes un enfoque aún mejor, pero esta versión es más flexible ya que le permite definir diferentes órdenes de clasificación.

Actualizar

Guava tiene esta funcionalidad integrada en su Orderingclase:

List<String> colorOrder = ImmutableList.of("red","green","blue","yellow");
final Ordering<String> colorOrdering = Ordering.explicit(colorOrder);
Comparator<Car> comp = new Comparator<Car>() {
    @Override
    public int compare(Car o1, Car o2) {
        return colorOrdering.compare(o1.getColor(),o2.getColor());
    }
}; 

Esta versión es un poco menos detallada.


Actualizar de nuevo

Java 8 hace que el Comparador sea aún menos detallado:

Comparator<Car> carComparator = Comparator.comparing(
        c -> definedOrder.indexOf(c.getColor()));
Sean Patrick Floyd avatar Mar 09 '2011 11:03 Sean Patrick Floyd