使用正则表达式对字符串的ArrayList进行排序

时间:2012-01-24 13:25:30

标签: java string sorting arraylist

我有一个字符串值的ArrayList(它们需要格式化),我需要按年份排序。该列表如下:

01-05-2011
11-24-2011
01-12-2012
...

我目前按月按字母顺序排序,但我想知道如何按年份排序这个字符串ArrayList。

5 个答案:

答案 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.sortstable,因此,如果您的字符串已按月排序,并按年份排序,则同一年的字符串组仍将按月排序。

理想情况下,您应该将列表转换为字符串以外的其他内容列表,例如,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;
            }

        }
    });