Java 带数字和范围的字符串排序列表
输入列表:3年,5-7年,3-6年,3-8年,3-5年,5年 预期产出清单:3年、3-5年、3-6年、3-8年、5年、5-7年 我想像上面所示那样对字符串列表进行排序,我尝试在数组列表中使用Collection.sort,但没有得到预期的输出。我的输出如下所示。带连字符的字符串显示在不带连字符的字符串之前。但它正在得到整理Java 带数字和范围的字符串排序列表,java,android,sorting,arraylist,Java,Android,Sorting,Arraylist,输入列表:3年,5-7年,3-6年,3-8年,3-5年,5年 预期产出清单:3年、3-5年、3-6年、3-8年、5年、5-7年 我想像上面所示那样对字符串列表进行排序,我尝试在数组列表中使用Collection.sort,但没有得到预期的输出。我的输出如下所示。带连字符的字符串显示在不带连字符的字符串之前。但它正在得到整理 我的输出排序列表:3-5年、3-6年、3-8年、3年、5-7年、5年,您的列表有字符串,因此Collections.sort根据字符串比较对列表进行排序。如果您希望它以不同方
我的输出排序列表:3-5年、3-6年、3-8年、3年、5-7年、5年,您的列表有字符串,因此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]
在混合物中再加一个。我们当然可以编写更可读的代码,但要添加一个简洁的代码
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()));
编写一个合适的比较器。您需要捕获字符串中的年份,如前所述,在这些年份的基础上使用合适的比较器。基于concat的排序将在您达到两位数或更多年份时立即中断,例如,添加3-50年和30-50年将导致:[3年,30-50年,3-5年,3-50年,3-6年,3-8年,5-7年]
3 years
3 - 5 years
3 - 6 years
3 - 8 years
3 - 50 years
5 years
5 - 7 years
30 - 50 years