我有一个字符串值的ArrayList(它们需要格式化),我需要按年份排序。该列表如下:
01-05-2011
11-24-2011
01-12-2012
...
我目前按月按字母顺序排序,但我想知道如何按年份排序这个字符串ArrayList。
答案 0 :(得分:7)
Collections.sort(
myList, new Comparator<String>() {
@Override
public int compare(String a, String b) {
// If a is "11-24-2012", then aLastDash points
// here ---------^.
int aLastDash = a.lastIndexOf("-");
int bLastDash = b.lastIndexOf("-");
return a.substring(aLastDash+1).compareTo(
b.substring(bLastDash+1));
}
});
Collections.sort
使用Comparator
指定如何比较两个列表值。您的案例中的列表值为String
秒。你可以按字典顺序比较每个字符串的最后4位数字,然后就完成了。
Collections.sort
为stable,因此,如果您的字符串已按月排序,并按年份排序,则同一年的字符串组仍将按月排序。
理想情况下,您应该将列表转换为字符串以外的其他内容列表,例如,Joda时间日期。现在这段代码是stringly typed。您越早接受输入并将它们强制转换为有意义的对象,您的代码越少,输入假设就越少,当您的假设不完全保留时,您需要调试的代码行数就越少。
答案 1 :(得分:4)
我不会使用正则表达式 - 基本上你应该实现Comparator<String>
来比较任何两个字符串。您可以通过重新排列字符串的位(例如,以yyyyMMdd格式)然后执行字典比较来执行此操作,或者您可以将字符串解析为日期并比较两个日期。
无论哪种方式,你都要将比较器传递给Collections.sort()
。
请注意,此建议会对它们进行完全排序 - 按年份,按月份,然后按天计算。如果你只是按年排序,它们仍然不会按照实际的时间顺序排列。我个人会完全按时间顺序完成它,因为这可能会在以后减少意外。
答案 2 :(得分:2)
如果您使用regexp,请将您的字符串转换为:
String toCompare = monthDayYearString.replaceAll(
"(\\d\\d)-(\\d\\d)-(\\d\\d\\d\\d)"
, "$3$1$2"
);
此表达式捕获日期的元素,并重新排序它们以使更慢的元素更接近字符串的开头。现在可以按字母顺序对字符串进行排序。
答案 3 :(得分:1)
使用Collections.sort
并构建一个使用正则表达式的Comparator
。
答案 4 :(得分:1)
我在这里结合了两个建议的解决方案..
Arrays.sort(new String[] {}, new Comparator<String>() {
private final Pattern p = Pattern.compile("(\\d\\d)-(\\d\\d)-(\\d\\d\\d\\d)");
@Override
public int compare(String o1, String o2) {
Matcher m1 = p.matcher(o1);
Matcher m2 = p.matcher(o2);
int compareYear = m1.group(3).compareTo(m2.group(3));
if (compareYear == 0) {
int compareMonth = m1.group(1).compareTo(m2.group(1));
if (compareMonth == 0) {
return m1.group(2).compareTo(m2.group(2));
} else {
return compareMonth;
}
} else {
return compareYear;
}
}
});