-3

I am trying to sort this logically Suppose I have a list of strings that have the follow elements

String[] myList = {"Spring 2013", "Fall 2009", "Fall 2010", "Spring 2012"};

I want to know how I can sort this where the result set would be Fall 2009, Fall 2010, Spring 2012, Spring 2013

I appreciate your help, thanks!

4

4 回答 4

2

假设您无法重新格式化字符串,您可以编写一个自定义比较器来实现该逻辑。您的比较器会调用 split 来分隔学期和年份。然后它可以先比较年份,然后是自定义月/学期逻辑。

您可以使用列表和自定义比较器调用 Collections.sort 或 Arrays.sort。

于 2013-10-30T00:12:09.237 回答
1

请注意,诸如“Spring”和“Fall”之类的季节名称比年份“不那么重要”,

此外,季节不按字母顺序排序,而是按冬季、春季、夏季、秋季(我假设?)。

因此,如果您将“Fall 2010”转换为“20104”,将“Spring 2013”​​转换为“20132”,那么您可以将它们按数字排序。

于 2013-10-30T00:11:34.307 回答
0

下面是Comparator#compare函数的样子:

int compare(String o1, String o2) {
   // null values always prioritized
   if (o1 == o2) return 0;
   if (o1 == null) return -1;
   if (o2 == null) return 1;

   String[] parts1 = o1.split(' '); // e.g. ["Fall", "2012"]
   String[] parts2 = o2.split(' ');

   // invalid data, just throw some nonsense ordering out
   if (parts1.length != 2 || parts2.length != 2) {
     return parts2.length - parts1.length;
   }

   // have winner, 4 digit years can be compared lexicographical
   var yearCompare = parts[1].compareTo(parts[2]);
   if (yearCompare != 0) {
     return yearCompare;
   }

   // map term names to orderable values
   String[] termWeights = { "Spring", "Summer", "Fall", "Winter" };
   var term1 = termWeights.indexOf(parts1[0]);
   var term2 = termWeights.indexOf(parts2[0]);

   // invalid terms prioritized
   if (term1 == term2) return 0;
   if (term1 == -1) return -1;
   if (term2 == -1) return 1;

   return term2 - term1;
}

当然,我根本没有测试过这个。YMMV :)

这是另一种替代方法(基于评论):

// swap "TermName Year" to "Year TermName"
String prioritizeYear (String i) {
   return i.replaceFirst("^(\\w+)\\s+(\\d+)", "$2_$1");
}

// convert "TermName" to "TermValue"
String weightTerm (String i) {
   return i.replace("Spring", "1")
           .replace("Summer", "2")
           .replace("Fall", "3")
           .replace("Winter", "4");
}

int compare(String o1, String o2) {
   // null values always prioritized
   if (o1 == o2) return 0;
   if (o1 == null) return -1;
   if (o2 == null) return 1;

   String n1 = weightTerm(prioritizeYear(o1));
   String n2 = weightTerm(prioritizeYear(o2));

   return n1.compareTo(n2);
}

再次,YMMV。

于 2013-10-30T00:27:50.340 回答
0

在这种情况下,所需的顺序是自然(字母)顺序,因此您可以使用该Arrays.sort(Object\[\])方法。如果所需的顺序与自然顺序不匹配,您可以实现 aComparator并使用该Arrays.sort(String\[\], Comparator<String>)方法。

一个实现的例子Comparator(只是为了展示它是如何工作的):

public class SemesterComparator implements Comparator<String> {

    private static final List<String> SEASONS = Arrays.asList("Spring", "Summer", "Fall", "Winter");

    @Override
    public int compare(String one, String two) {
        String[] partsOne = one.split(" ");
        String[] partsTwo = two.split(" ");
        if (partsOne.length != 2 || partsTwo.length != 2) {
            throw new IllegalArgumentException();
        }
        if (!SEASONS.contains(partsOne[0]) || !SEASONS.contains(partsTwo[0])) {
            throw new IllegalArgumentException();
        }

        // compare years
        int comparison = partsOne[1].compareTo(partsTwo[1]);
        if (comparison == 0) {
            // if years are equal: compare season
            comparison = SEASONS.indexOf(partsOne[0]).compareTo(SEASONS.indexOf(partsTwo[0]));
        }
        return comparison;
    }
}

但正如评论中已经提到的,最好将值存储在可更好排序的格式或类中。

于 2013-10-30T00:12:46.163 回答