[英]Java - How to sort an ArrayList of Strings with seasons and years?
[英]Java - Custom Sort ArrayList of Strings
我想按特定顺序对长度为1或2的字符串的ArrayList进行排序。
订单是
1m, 2m, 3m ... 9,, 1p...9p, 1s...9s, E, S, W, N,Wd, Gd, Rd
如果你有主意?
例如,ArrayList是;
N 2p 9s 9s 1p 9m N 4s 1m 5p 7m 2s 5s 5m
我正在尝试在该ArrayList是将其按所需顺序放置的字段的类中编写一个方法。
相似的问题指向比较器,但是我发现每个解释都非常混乱,但是无论如何我做的都不一样。
只需完全将订单写完即可,Id非常好。
由于我主张重新打开它,因此下面的Comparator<String>
可以满足您的要求:
package testJ;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class WeirdOrderComparator implements Comparator<String> {
private static List<String> COMPASS_ORDER = Arrays.asList("E:S:W:N"
.split(":"));
private static List<String> D_ORDER = Arrays.asList("W:G:R".split(":"));
private static List<String> SUFFIX_ORDER = Arrays.asList("m:p:s::d"
.split(":"));
private int indexFor(String target, List<String> order) {
int r = order.indexOf(target);
if (r < 0) {
return order.size();
} else {
return r;
}
}
private int getSuffixNumber(String s) {
switch (s.length()) {
case 1:
return indexFor("", SUFFIX_ORDER);
case 2:
return indexFor(s.substring(1), SUFFIX_ORDER);
default:
return 99;
}
}
private int getWithinGroupNumber(int suffixGroup, String s) {
switch (suffixGroup) {
case 0:
case 1:
case 2:
return Integer.valueOf(s.substring(0, s.length() - 1));
case 3:
return indexFor(s, COMPASS_ORDER);
case 4:
return indexFor(s.substring(0, 1), D_ORDER);
default:
return 99;
}
}
public int compare(String o1, String o2) {
int sfx1 = getSuffixNumber(o1);
int sfx2 = getSuffixNumber(o2);
if (sfx1 != sfx2) {
return sfx1 - sfx2;
}
int grp1 = getWithinGroupNumber(sfx1, o1);
int grp2 = getWithinGroupNumber(sfx2, o2);
if (grp1 != grp2) {
return grp1 - grp2;
}
return o1.compareTo(o2);
}
}
它可以用作:
package testJ;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class WeirdOrderTest {
public static void main(String args[]) {
List<String> testList = Arrays.asList("N 2p 9s 9s 1p 9m N 4s 1m 5p 7m 2s 5s 5m".split(" "));
System.out.println("Original order: " + testList);
ArrayList<String> sorted = new ArrayList<String>();
sorted.addAll(testList);
Collections.sort(sorted, new WeirdOrderComparator());
System.out.println("Sorted: " + sorted);
}
}
这将产生:
Original order: [N, 2p, 9s, 9s, 1p, 9m, N, 4s, 1m, 5p, 7m, 2s, 5s, 5m]
Sorted: [1m, 5m, 7m, 9m, 1p, 2p, 5p, 2s, 4s, 5s, 9s, 9s, N, N]
这里的一般策略是:
找到可以区分两个字符串的规则。 在这种情况下,我首先确定字符串的一般“组”:以“ m”,“ p”,“ s”结尾,单个字母或以“ d”结尾的事物。
如果该规则将两个输入区分开,则如果o1
首先出现,则返回负数,如果o1
随后出现,则返回正数。 为了记住这一约定,请考虑“如果o1
和o2
是小整数,则就像o1 - o2
”(忽略溢出)。
如果该规则不能区分o1
和o2
,请找到另一个规则, o1
o2
。
最后,如果您用完规则,则返回0或委托其他比较。
请记住,您的Comparator
应该合理地处理您不期望的字符串-它可以引发异常(因为如果您给它赋予“ Xs”,它将引发异常),但是如果它不引发异常,则结果应为一致的。 也就是说,如果compare(x, y) < 0
且compare(y, z) < 0
则如果compare(x, z)
没有引发异常,则不管x
是什么, compare(x, z)
必须为负。 , y
和z
为。 确保比较器的一种方法是按照我在此处所做的方式构造比较器,在该方法中,我为每个字符串找到一系列“订单号”,然后如果订单号无济于事,则委托给String.compareTo
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.