Java Использование компараторов в сочетании с пользовательскими компараторами - PullRequest
0 голосов
/ 21 мая 2018

Я хочу отсортировать следующий список примеров, который в настоящее время содержит только строки со своими собственными правилами.

ArrayList<String> coll = new ArrayList<>();
coll.add("just");
coll.add("sdsd");
coll.add("asb");
coll.add("b as");
coll.add("just");
coll.add("dhfga");
coll.add("jusht");
coll.add("ktsa");
coll.add("just");
coll.add("just");

Я знаю, что мог бы написать свой собственный компаратор для этого, но, как я знаю, Java такжеУ меня есть компараторы, которые частично решают эту проблему. Я хочу знать, как я могу использовать те из Java API в комбинации с моим собственным.


Как это должно быть отсортировано?

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

Comparator.naturalOrder() сортирует список в алфавитном порядке, но как мне объединить этот компаратор с пользовательским, который проверяет, является ли слово just или чем-то еще.

Ответы [ 3 ]

0 голосов
/ 21 мая 2018

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

Map<String, Integer> orderMap = new HashMap<>();
int order = 0;
for(String specialWord : yourListOfSpecialWords){
    orderMap.put(specialWord, order++);
}

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

Comparator<String> comparator = ((Comparator<String>) (o1, o2) -> {
    int leftScore = orderMap.getOrDefault(o1, Integer.MAX_VALUE);
    int rightScore = orderMap.getOrDefault(o2, Integer.MAX_VALUE);
    return Integer.compare(leftScore, rightScore);
}).thenComparing(String::compareTo);

Используйте этот компаратор для сортировки списка.Примечание: вы, вероятно, хотите инициализировать свою карту только один раз и хранить ее в константе или, по крайней мере, в кэше.

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

0 голосов
/ 23 мая 2018

Вы можете интегрировать критерии в компаратор, например

coll.sort(Comparator.comparing((String s) -> !s.equals("just"))
                    .thenComparing(Comparator.naturalOrder()));

, или разделить операции, сначала переместив все вхождения "just" вперед, а затем отсортировав только остальные элементы:

int howManyJust = 0;
for(int ix = 0, num = coll.size(); ix < num; ix++)
    if(coll.get(ix).equals("just") && ++howManyJust <= ix)
        Collections.swap(coll, ix, howManyJust-1);

coll.subList(howManyJust, coll.size()).sort(Comparator.naturalOrder());

, хотя это может показаться более сложным, но потенциально более эффективно, особенно для больших списков.

0 голосов
/ 21 мая 2018

Вы можете сделать это примерно так:

coll.sort(Comparator
    .comparingInt((String s) -> s.equals("just") ? 0 : 1) // Words "just" first
    .thenComparing(Comparator.naturalOrder())); // Then others
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...