Сортировать ArrayList строк с помощью регулярных выражений - PullRequest
3 голосов
/ 24 января 2012

У меня есть ArrayList значений String (они должны быть отформатированы как таковые), которые мне нужно отсортировать по годам.Список выглядит следующим образом:

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

В настоящее время они отсортированы в алфавитном порядке по месяцам, но мне было интересно, как я могу отсортировать ArrayList of Strings по годам.

Ответы [ 5 ]

7 голосов
/ 24 января 2012
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 равно стабильно , поэтому, если ваши строки уже отсортированы по месяцам, и вы сортируете поyear, группы строк с одинаковым годом все равно будут отсортированы по месяцам.

В идеале, вы должны преобразовать свой список в список чего-то, кроме строк, например, даты времени Joda.Прямо сейчас этот код строго типизирован .Чем раньше вы берете входные данные и приводите их к значимым объектам, тем меньше в вашем коде приходится делать предположений на входе, тем меньше строк кода вы должны отлаживать, когда ваши предположения не совсем верны.

4 голосов
/ 24 января 2012

Я бы не использовал для этого регулярное выражение - в основном вы должны реализовать Comparator<String> для сравнения любых двух строк. Это можно сделать, просто переставив биты строки (например, в формат yyyyMMdd), а затем выполнив лексикографическое сравнение, или можно проанализировать строку как дату и сравнить две даты.

В любом случае, вы бы передали компаратор в Collections.sort().

Обратите внимание, что это предложение полностью рассортирует их по годам, месяцам и дням. Если вы просто сортируете по годам, они все равно не будут в реальном хронологическом порядке. Лично я хотел бы сделать это полностью в хронологическом порядке, поскольку это, вероятно, вызовет меньше сюрпризов позже.

2 голосов
/ 24 января 2012

Если вы используете регулярное выражение, преобразуйте вашу строку следующим образом:

String toCompare = monthDayYearString.replaceAll(
    "(\\d\\d)-(\\d\\d)-(\\d\\d\\d\\d)"
,   "$3$1$2"
);

Это выражение захватывает элементы вашей даты и переупорядочивает их, чтобы приблизить медленно меняющиеся элементы к началу.строки.Теперь строки можно сортировать по дате в алфавитном порядке.

1 голос
/ 24 января 2012

Я объединил 2 предложенных решения здесь ..

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;
            }

        }
    });
1 голос
/ 24 января 2012

Используйте Collections.sort и создайте Comparator, который использует регулярные выражения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...