繁体   English   中英

用数字和范围排序字符串列表

[英]Sorting list of strings with numbers and ranges

输入列表: "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,但没有得到预期的输出。 我的输出如下所示。 带连字符的字符串显示在不带连字符的字符串之前。 但它得到排序。

我的输出排序列表: "3 - 5 years","3 - 6 years","3 - 8 years","3 years","5 - 7 years","5 years",

您的列表包含字符串,因此Collections.sort()已根据字符串比较对列表进行排序。
如果您希望它以不同的方式排序,则必须使用合适的 Comparator ,请尝试以下代码:

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]

在混合物中添加另一个。 你当然可以写出更具可读性的代码,但添加一个简洁的代码

    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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM