[英]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.