我试图在逻辑上对此进行排序 假设我有一个包含以下元素的字符串列表
String[] myList = {"Spring 2013", "Fall 2009", "Fall 2010", "Spring 2012"};
我想知道如何对结果集进行排序 2009年秋季,2010年秋季,2012年春季,2013年春季
感谢您的帮助,谢谢!
答案 0 :(得分:2)
假设您无法重新格式化字符串,您可以编写实现该逻辑的自定义比较器。你的Comparator会调用split来分开学期和年份。然后它可以比较第一年,然后是自定义月/学期逻辑。
您可以使用列表和自定义比较器调用Collections.sort或Arrays.sort。
答案 1 :(得分:1)
请注意,“春天”和“秋季”等季节名称比年份“重要”,
此外,季节不是按字母顺序排序,而是按冬季,春季,夏季,秋季(我假设?)。
因此,如果您将“Fall 2010”转换为“20104”和“Spring 2013”转换为“20132”,那么您可以将它们排序为数字。
答案 2 :(得分:0)
在这种情况下,所需的顺序是自然(按字母顺序)顺序,因此您可以使用Arrays.sort(Object\[\])
方法。如果所需订单与自然订单不符,您可以实施Comparator
并使用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;
}
}
但正如评论中已经提到的那样,最好将值存储在可以更好排序的格式或类中。
答案 3 :(得分: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。