Страницы

Поиск по вопросам

вторник, 24 декабря 2019 г.

Как правильно сортировать Enum?

#java #алгоритм #сортировка #enum


Например я хочу отсортировать Enum

UPDATED:

public class Main {

    public static void main(String[] args) throws Exception {

        Bean[] mass = new Bean[] { new Bean(new Object(), A), new Bean(new Object(),
C), new Bean(new Object(), D),
                new Bean(new Object(), B), new Bean(new Object(), A) }; // 1, 3, 4, 2, 1
        Arrays.sort(mass, new EnumComparator());
        System.out.println(Arrays.toString(mass)); //[1, 1, 2, 3, 4]

    }
}

class EnumComparator implements Comparator {

    @Override
    public int compare(Bean o1, Bean o2) {
        return o1.key.toString().compareTo(o2.key.toString());
    }

}

class Bean {
    public Object data;
    public Enum key;

    public Bean(Object data, Enum key) {
        super();
        this.data = data;
        this.key = key;
    }

    @Override
    public String toString() {
        return key.toString();
    }

}

enum MyEnum {

    D("4"),
    A("1"),
    B("2"),
    C("3");

    private String index;

    private MyEnum(String index) {
        this.index = index;
    }

    @Override
    public String toString() {
        return index;
    }

}


Сортировка Arrays.sort использует TimSort или MergeSort время работы в среднем  O(n
log n). Но если мы используем конечное количество констант (Enums), можно использовать
сортировку подсчетом за время  O(n). Есть ли стандартный механизм для использования
сортировки подсчетом для Enums в java?
    


Ответы

Ответ 1



У деревьев Θ(log(n)). Это быстрее, чем O(n) или O(n log n). Set set = new TreeSet<>(Comparator.comparing(MyEnum::toString)); set.addAll(Arrays.asList(MyEnum.values())); // [4, 1, 2, 3] System.out.println(set); // [1, 2, 3, 4] Если операция addAll для вас медленная и элементов много, - set контейнер можно формировать по мере инициализации/загрузки самого MyEnum'а: public class SortingEnum { public static void main(String[] args) { System.out.println(set); // [1, 2, 3, 4] } private final static Set set = new TreeSet<>(Comparator.comparing(MyEnum::toString));; static { synchronized (MyEnum.A) {} } // manual enum class load enum MyEnum { C("3"), A("1"), D("4"), B("2"), ; private final String s; MyEnum(String s) { this.s = s; set.add(this); } @Override public String toString() { return s; } } } Updated: Из вашего нового примера, вы хотите отсортировать Bean по его внутреннему полю Enum, с учётом того, что элементы Bean могу повторяться. Тогда элементы Bean могут реальзовать интерфейс Comparable, где указать, что сортировка нужна по ключю Enum, либо передать компаратор в конструктор TreeMultiset.create(new EnumComparator()) и можно воспользоваться Google Guava коллекцией TreeMultiset: com.google.guava guava 23.6-jre import com.google.common.collect.TreeMultiset; import java.util.Arrays; import java.util.Comparator; public class SortingBeanByEnum { public static void main(String[] args) { TreeMultiset multiset = TreeMultiset.create(new EnumComparator()); multiset.addAll(Arrays.asList(new Bean(new Object(), MyEnum.A), new Bean(new Object(), MyEnum.C), new Bean(new Object(), MyEnum.D), new Bean(new Object(), MyEnum.B), new Bean(new Object(), MyEnum.A))); System.out.println(multiset); // [1 x 2, 2, 3, 4] System.out.println(multiset.descendingMultiset()); // [4, 3, 2, 1 x 2] System.out.println(multiset.count(new Bean(new Object(), MyEnum.A))); // 2 System.out.println(Arrays.toString(multiset.toArray())); // [1, 1, 2, 3, 4] } } class EnumComparator implements Comparator { @Override public int compare(Bean o1, Bean o2) { return o1.key.toString().compareTo(o2.key.toString()); } } class Bean/* implements Comparable*/ { public Object data; public MyEnum key; public Bean(Object data, MyEnum key) { this.data = data; this.key = key; } @Override public String toString() { return key.toString(); } /*@Override public int compareTo(Bean bean) { return key.toString().compareTo(bean.key.toString()); }*/ } enum MyEnum { D("4"), A("1"), B("2"), C("3"); private String index; private MyEnum(String index) { this.index = index; } @Override public String toString() { return index; } }

Комментариев нет:

Отправить комментарий