Как отсортировать список строк, где сначала идут строки с startWith, а затем endWith - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть список строк например

**united**abc
**united**abcd
abcd**united**
**united**abcde
asdasdad**united**
**united**a

сортируется по длине строк, но моя идея сортировать как

**united**a 
**united**abc
**united**abcd
**united**abcde
abcd**united**
asdasdad**united**

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

Я пробовал это, но это не работает

 if (o1.name.toLowerCase().startsWith(query)) {
    return@Comparator  -1
  } else if (o2.name.toLowerCase().startsWith(query)) {
    return@Comparator  1
  } else {
    return@Comparator 0
  }

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

Вам нужно 3 компаратора для читабельности.
Один, чтобы выяснить, находится ли объединенный впереди, а затем упорядочить по нему.
Один, чтобы выяснить, есть ли объединенный, находится сзади, а затем упорядочить по нему.
Один, чтобы найти порядок, если объединенный не содержится, или оба имеют одинаковый объединенный приоритет, например. o1.unitedFront && o2.unitedFront или o1.unitedEnd && o2.unitedEnd.

В настоящее время вы не думаете о случаях, когда обе строки содержат объединенные, потому что вы предполагаете, что если первая содержит, то другая нет.

0 голосов
/ 07 сентября 2018

Будет гораздо более разборчивым и, следовательно, менее подверженным ошибкам комбинировать условия компаратора с использованием методов Comparator.comparing и thenComparing:

list.sort(Comparator.comparing((String str) -> !str.startsWith(query))
        .thenComparing(str -> !str.endsWith(query))
        .thenComparingInt(String::length)
        .thenComparing(Comparator.naturalOrder()));

Причина символа ! заключается в том, что наши истины будут сортироваться раньше ложных.

0 голосов
/ 07 сентября 2018

Проблема вашего компаратора в том, что он нарушает ограничения, когда оба входа начинаются или заканчиваются строкой query. Например, когда o1 и o2 * name начинаются с "united", ваш компаратор вернет -1 как для o1.compareTo(o2), так и для его противоположного o2.compareTo(o1), что является непоследовательным и, следовательно, отбрасывает алгоритм сортировки.

Вам нужно изменить код, чтобы проверить обе стороны на startsWith и endsWith, прежде чем продолжить:

String n1 = o1.name.toLowerCase();
String n2 = o2.name.toLowerCase();
// Both startsWith / both endsWith
if ((n1.startsWith(query) && n2.startsWith(query))
||  (n1.endsWith(query) && n2.endsWith(query))) {
    return Integer.compare(n1.length(), n2.length());
}
// Only one startsWith
if (n1.startsWith(query)) {
    return -1;
}
if (n2.startsWith(query)) {
    return 1;
}
// only one endsWith
if (n1.endsWith(query)) {
    return 1;
}
if (n2.endsWith(query)) {
    return -1;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...