Вопрос-ответ

How do I use Comparator to define a custom sort order?

Как мне использовать Comparator для определения пользовательского порядка сортировки?

Я хочу разработать демонстрационную версию сортировки для списка автомобилей. Я использую таблицу данных для отображения списка автомобилей. Теперь на самом деле я хочу отсортировать список по цвету автомобиля. Здесь сортировка не по алфавиту. Я хочу использовать свой пользовательский порядок сортировки, например, сначала красная машина, затем синяя и т.д.

Для этого я пытаюсь использовать Java Comparator и Comparable, но это позволяет сортировать только в алфавитном порядке.

Итак, кто-нибудь может подсказать мне, как реализовать используемый метод, чтобы сортировка стала быстрее.

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
}
}
Переведено автоматически
Ответ 1

Я рекомендую вам создать перечисление для цветов вашего автомобиля вместо использования строк, и естественным порядком перечисления будет порядок, в котором вы объявляете константы.

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

и

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

Вы меняете строку на PaintColor, а затем в main ваш список car становится:

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

...

Collections.sort(carList, new ColorComparator());
Ответ 2

Как насчет этого:

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

В принципе, я согласен, что использование enum - еще лучший подход, но эта версия более гибкая, поскольку позволяет определять разные порядки сортировки.

Обновить

УGuava эта функциональность встроена в его Ordering класс:

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

Эта версия немного менее подробная.


Снова обновить

Java 8 делает Comparator еще менее подробным:

Comparator<Car> carComparator = Comparator.comparing(
c -> definedOrder.indexOf(c.getColor()));
Ответ 3

Comparator в строке ...

List<Object> objList = findObj(name);
Collections.sort(objList, new Comparator<Object>() {
@Override
public int compare(Object a1, Object a2) {
return a1.getType().compareToIgnoreCase(a2.getType());
}
});
Ответ 4

Я думаю, это можно сделать следующим образом:

class ColorComparator implements Comparator<CarSort>
{
private List<String> sortOrder;
public ColorComparator (List<String> sortOrder){
this.sortOrder = sortOrder;
}

public int compare(CarSort c1, CarSort c2)
{
String a1 = c1.getColor();
String a2 = c2.getColor();
return sortOrder.indexOf(a1) - sortOrder.indexOf(a2);
}
}

Для сортировки используйте это:

Collections.sort(carList, new ColorComparator(sortOrder));
java enums