Сортировка массива с учетом двух компараторов?

скажем, у меня есть два компаратора, первичный и вторичный. Как я могу отсортировать массив сначала по первичному компаратору, а затем по вторичному?

скажем, что каждый объект имеет имя и числовое поле.

Как

Bob 1
Bob 2
Jack 1
Jack 2

возможно ли это без создания нового компаратора?

3 ответов


Да, вы можете выполнить сортировку без создания нового компаратора.

есть известный трюк для сортировки по первичному полю, вторичному, третичному и т. д.: Сначала сортировка по наименее важному полю (третичному), затем по следующему важному полю (вторичному) и, наконец, по наиболее важному полю (первичному). Но алгоритм сортировки должен быть стабильный для этого, чтобы работать.

если вы сортируете массив, используйте Arrays.sort(). Если вы сортируете List используйте Collections.sort(). Оба этих метода гарантированно стабильны.

Предположим ваш основной объект компаратора хранится в переменной primaryComp, и вторичное-в secondaryComp. Тогда вот некоторый код, чтобы выполнить то, что вы хотите:

Arrays.sort(mylist, secondaryComp);  // This must come first!
Arrays.sort(mylist, primaryComp);

предполагая, что ваш класс

class X {
    String name;
    int num;
}

тогда сортировка будет

Arrays.sort(x, new Comparator<X>() {
        @Override
        public int compare(X o1, X o2) {
            if (o1.name.equals(o2.name)) {
                return Integer.compare(o1.num, o2.num);
            }
            return o1.name.compareTo(o2.name);
        }});

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

class FullName {
    public String firstName;
    public String secondName;
}

скажем, вы создаете новое имя, называемое BobBobbins, назначьте значения, а затем просто сравните сначала второе имя, а затем первое имя. Вы можете иметь статическую функцию для сравнения:

public static bool compareTo ( FullName name1, FullName name2 ) {
    // Algorithm here
}

если вы используете статический компаратор, вы можете сделать это:FullName.compareTo( BobBobbins, CharlieChaplin );