Компаратор на основе настраиваемого порядка

Есть ли способ написать собственный компаратор, следуя этому примеру:

В большинстве случаев не более 10 предметов в случайном порядке т.е.

first item:  item_one
second:      second_one
third:       third_one

Я хочу, чтобы результат был отсортирован следующим образом: second_one, third_one, first_one. Я хотел бы вытащить этот заказ из файла конфигурации, вроде шаблона для сортировки.

Я использую неправильную структуру данных, есть ли у кого-нибудь опыт с этим?

Ответ 1

Конечно. Вот "OrderedComparator", который сравнивает элементы в соответствии с предопределенным порядком:

class OrderedComparator implements Comparator<String> {

    List<String> predefinedOrder;

    public OrderedComparator(String[] predefinedOrder) {
        this.predefinedOrder = Arrays.asList(predefinedOrder);
    }

    @Override
    public int compare(String o1, String o2) {
        return predefinedOrder.indexOf(o1) - predefinedOrder.indexOf(o2);
    }

}

И вот несколько тестовых кодов. (Я использовал List вместо Set, так как он 1) выглядит более естественным, когда речь идет о порядке элементов и 2) лучше иллюстрирует, что происходит с повторяющимися элементами при сортировке с использованием этого компаратора.)

class Test {

    public static void main(String[] args) {

        // Order (could be read from config file)
        String[] order = { "lorem", "ipsum", "dolor", "sit" };


        List<String> someList = new ArrayList<String>();

        // Insert elements in random order.
        someList.add("sit");
        someList.add("ipsum");
        someList.add("sit");
        someList.add("lorem");
        someList.add("dolor");
        someList.add("lorem");
        someList.add("ipsum");
        someList.add("lorem");


        System.out.println(someList);

        Collections.sort(someList, new OrderedComparator(order));

        System.out.println(someList);
    }

}

Вывод:

[sit, ipsum, sit, lorem, dolor, lorem, ipsum, lorem]
[lorem, lorem, lorem, ipsum, ipsum, dolor, sit, sit]

Ответ 2

Взгляните на TreeSet (http://download.oracle.com/javase/6/docs/api/java/util/TreeSet.html). Вы можете предоставить пользовательский Компаратор в конструкторе. Этот компаратор будет учитывать ваш конфиг. файл. Логика компаратора не будет довольно, хотя, поскольку вы хотите произвольный порядок. Вы, скорее всего, закончите перечисление всех возможных сравнений.

Ответ 3

В наборе хранятся неупорядоченные элементы. Если вы хотите сравнивать и сортировать, вы, вероятно, должны пойти со списком. Вот вам быстрый фрагмент:

List<X> sorted = new ArrayList<X>(myset);
Collections.sort(sorted, new Comparator<X>() {
    public int compare(X o1, X o2) {
        if (/* o1 < o2 */) {
            return -1;
        } else if (/* o1 > o2 */) {
            return 1;
        } else {
            return 0;
        }
    }
});

Теперь у вас есть sorted, который имеет все те же элементы myset, который был неупорядочен из-за того, что он является множеством.

Вы также можете посмотреть TreeSet, который упорядочивает его элементы, но обычно не рекомендуется полагаться на упорядоченный набор.