Я хочу разработать демонстрацию сортировки для списка автомобилей. Я использую таблицу данных для отображения списка автомобилей. Теперь я хочу отсортировать список по цвету машины. Здесь он не сортируется по алфавиту. Я хочу использовать свой собственный порядок сортировки: сначала идет красная машина, затем синяя и т. Д.
Для этого я пытаюсь использовать 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
}
}
enum
значений - это порядок, в котором определены его значения.Как насчет этого:
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()));
Компаратор в линию ...
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()); } });
источник
Думаю, это можно сделать так:
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));
источник
Мне пришлось сделать что-то похожее на ответ Шона и ilalex.
Но у меня было слишком много вариантов, чтобы явно определить порядок сортировки, и мне нужно было только поместить определенные записи в начало списка ... в указанном (неестественном) порядке.
Надеюсь, это поможет кому-то другому.
public class CarComparator implements Comparator<Car> { //sort these items in this order to the front of the list private static List<String> ORDER = Arrays.asList("dd", "aa", "cc", "bb"); public int compare(final Car o1, final Car o2) { int result = 0; int o1Index = ORDER.indexOf(o1.getName()); int o2Index = ORDER.indexOf(o2.getName()); //if neither are found in the order list, then do natural sort //if only one is found in the order list, float it above the other //if both are found in the order list, then do the index compare if (o1Index < 0 && o2Index < 0) result = o1.getName().compareTo(o2.getName()); else if (o1Index < 0) result = 1; else if (o2Index < 0) result = -1; else result = o1Index - o2Index; return result; } //Testing output: dd,aa,aa,cc,bb,bb,bb,a,aaa,ac,ac,ba,bd,ca,cb,cb,cd,da,db,dc,zz }
источник
Я сделаю примерно так:
List<String> order = List.of("Red", "Green", "Magenta", "Silver"); Comparator.comparing(Car::getColor(), Comparator.comparingInt(c -> order.indexOf(c)))
Все кредиты принадлежат @Sean Patrick Floyd :)
источник
В Java 8 вы можете сделать что-то вроде этого:
Сначала вам понадобится Enum:
public enum Color { BLUE, YELLOW, RED }
Класс автомобиля:
public class Car { Color color; .... public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } }
А затем, используя список автомобилей, вы можете просто:
источник
Определите один тип перечисления как
public enum Colors { BLUE, SILVER, MAGENTA, RED }
Изменить тип данных
color
сString
наColors
Изменить тип возвращаемого значения и тип аргумента метода получения и установки цвета наColors
Определите тип компаратора следующим образом
static class ColorComparator implements Comparator<CarSort> { public int compare(CarSort c1, CarSort c2) { return c1.getColor().compareTo(c2.getColor()); } }
после добавления элементов в список вызовите метод сортировки Collection, передав объекты списка и компаратора в качестве аргументов
т.е.
Collections.sort(carList, new ColorComparator());
затем распечатать с помощьюListIterator
.Полная реализация класса выглядит следующим образом:
package test; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.ListIterator; public class CarSort implements Comparable<CarSort>{ String name; Colors color; public CarSort(String name, Colors color){ this.name = name; this.color = color; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Colors getColor() { return color; } public void setColor(Colors color) { this.color = color; } //Implement the natural order for this class public int compareTo(CarSort c) { return getName().compareTo(c.getName()); } static class ColorComparator implements Comparator<CarSort> { public int compare(CarSort c1, CarSort c2) { return c1.getColor().compareTo(c2.getColor()); } } public enum Colors { BLUE, SILVER, MAGENTA, RED } public static void main(String[] args) { List<CarSort> carList = new ArrayList<CarSort>(); List<String> sortOrder = new ArrayList<String>(); carList.add(new CarSort("Ford Figo",Colors.SILVER)); carList.add(new CarSort("Santro",Colors.BLUE)); carList.add(new CarSort("Honda Jazz",Colors.MAGENTA)); carList.add(new CarSort("Indigo V2",Colors.RED)); Collections.sort(carList, new ColorComparator()); ListIterator<CarSort> itr=carList.listIterator(); while (itr.hasNext()) { CarSort carSort = (CarSort) itr.next(); System.out.println("Car colors: "+carSort.getColor()); } } }
источник
Используя простые циклы:
public static void compareSortOrder (List<String> sortOrder, List<String> listToCompare){ int currentSortingLevel = 0; for (int i=0; i<listToCompare.size(); i++){ System.out.println("Item from list: " + listToCompare.get(i)); System.out.println("Sorting level: " + sortOrder.get(currentSortingLevel)); if (listToCompare.get(i).equals(sortOrder.get(currentSortingLevel))){ } else { try{ while (!listToCompare.get(i).equals(sortOrder.get(currentSortingLevel))) currentSortingLevel++; System.out.println("Changing sorting level to next value: " + sortOrder.get(currentSortingLevel)); } catch (ArrayIndexOutOfBoundsException e){ } } } }
И порядок сортировки в списке
public static List<String> ALARMS_LIST = Arrays.asList( "CRITICAL", "MAJOR", "MINOR", "WARNING", "GOOD", "N/A");
источник