¿Cómo uso Comparator para definir un orden de clasificación personalizado?
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 Comparator
y Comparable
solo 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
}
}
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());
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 enum
es 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 Ordering
clase:
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()));