Сортировка списка строк с номерами и диапазонами - PullRequest
0 голосов
/ 28 февраля 2020

Список ввода: "3 years", "5 - 7 years", "3 - 6 years","3 - 8 years", "3 - 5 years", "5 years" Ожидаемый список вывода: "3 years","3 - 5 years","3 - 6 years","3 - 8 years","5 years", "5 - 7 years"

Я хочу отсортировать список строк, как показано выше, я пытался использовать Collection.sort в списке Array, но я не получаю ожидаемый результат. Мой вывод показан ниже. Строка с дефисом отображается перед строкой без дефиса. Но он сортируется.

Мой отсортированный список вывода: "3 - 5 years","3 - 6 years","3 - 8 years","3 years","5 - 7 years","5 years",

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

В вашем списке есть строки, поэтому Collections.sort() отсортировал список на основе сравнения строк. Если вы хотите, чтобы он сортировался по-другому, вы должны использовать подходящий компаратор , попробуйте следующий код:

ArrayList<String> list = new ArrayList<>();
list.add("3 years");
list.add("5 - 7 years");
list.add("3 - 6 years");
list.add("3 - 8 years");
list.add("3 - 5 years");
list.add("5 years");

// sort the list
Collections.sort(list, new Comparator<String>() {

  @Override
  public int compare(String o1, String o2) {
      // remove all the non - digits from the string
      String n1 = o1.replaceAll("\\D", "");
      String n2 = o2.replaceAll("\\D", "");
      return n1.compareTo(n2);
  }
});

System.out.println(list);
// output is 
// [3 years, 3 - 5 years, 3 - 6 years, 3 - 8 years, 5 years, 5 - 7 years]
0 голосов
/ 29 февраля 2020

Добавление еще одного в микс. Можно, конечно, написать более читаемый код, но добавив краткий

    Pattern rangePattern = Pattern.compile("(\\d+)(\\s-\\s(\\d+))?\\syears");
    Function<Map.Entry<String, Optional<List<Optional<String>>>>, Integer> getStartYear = e -> Integer.parseInt(e.getValue().flatMap(value -> value.get(0)).orElse("0"));
    Function<Map.Entry<String, Optional<List<Optional<String>>>>, Integer> getEndYear = e -> Integer.parseInt(e.getValue().flatMap(value -> value.get(1)).orElse("0"));
    Function<MatchResult, List<Optional<String>>> captureRangeYearsAsList = m -> List.of(Optional.ofNullable(m.group(1)), Optional.ofNullable(m.group(3)));

    List.of("3 years", "5 - 7 years", "3 - 6 years", "3 - 8 years", "3 - 5 years", "5 years", "3 - 50 years", "30 - 50 years").stream()
            .collect(Collectors.toMap(Function.identity(), s -> rangePattern.matcher(s).results()))
            .entrySet().stream()
            .map(e -> Map.entry(e.getKey(), e.getValue().map(captureRangeYearsAsList).findFirst()))
            .sorted(Comparator.comparing(getStartYear)
                    .thenComparing(getEndYear))
            .forEach(e -> System.out.println(e.getKey()));

Вывод

3 years
3 - 5 years
3 - 6 years
3 - 8 years
3 - 50 years
5 years
5 - 7 years
30 - 50 years
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...