我想实现我的自定义Comparator以这种特殊方式对键映射进行排序:
1
2
3
4
4a
4b
5
6
11
12
12a
...
我不知道怎么能完全做到。我只对数值进行了实例化处理:
aaa = new TreeMap<String, ArrayList<ETrack>>(
new Comparator<String>()
{
@Override
public int compare(String s1, String s2)
{
return Integer.valueOf(s1).compareTo(Integer.valueOf(s2));
}
});
但这并不是一个完整的解决方案。有什么想法吗?
答案 0 :(得分:2)
一种方法是将字符串映射到对象,并让这些对象实现Comparable
。
你可以做得更简单。如果你喜欢正则表达式,你可以使用这个技巧,即使它不太有效:
// Make sure not to compile the pattern within the method, to spare us some time.
Pattern p = Pattern.compile("^([0-9]+)([a-z]?)$");
/**
* Converts a string to a sortable integer, ensuring proper ordering:
* "1" becomes 256
* "1a" becomes 353
* "1b" becomes 354
* "2" becomes 512
* "100" becomes 25600
* "100a" becomes 25697
*/
int getSortOrder(String s) {
Matcher m = p.matcher(s);
if(!m.matches()) return 0;
int major = Integer.parseInt(m.group(1));
int minor = m.group(2).isEmpty() ? 0 : m.group(2).charAt(0);
return (major << 8) | minor;
}
像这样使用:
new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return getSortOrder(s1) - getSortOrder(s2);
}
}
答案 1 :(得分:1)
这是一个单行:
aaa = new TreeMap<String, ArrayList<ETrack>>(Comparators
.comparingInt(s -> Integer.parseInt(s.replaceAll("\\D", "")))
.thenComparing(s -> s.replaceAll("\\d", "")));
仅供参考\D
匹配非数字,\d
匹配数字。
顺便说一句,无论数字和非数字部分的顺序如何,这都会有效。
答案 2 :(得分:0)
如果你只有一个字母而不是更多, 你可以尝试这样的事情:
aaa = new TreeMap<String, ArrayList<ETrack>>(
new Comparator<String>()
{
@Override
public int compare(String s1, String s2)
{
String newS1=s1;
String newS2=s2;
char s1Letter=0;
char s1Letter=0;
//checks if last char is not a digit by ascii
if(!(s1.charAt(s1.length()-1)>=48 && s1.charAt(s1.length()-1)<=57)){
newS1 = s1.substring(0,s1.length()-1);
s1Letter = s1.charAt(s1.length()-1);
}
if(!(s2.charAt(s2.length()-1)>=48 && s2.charAt(s2.length()-1)<=57)){
newS2 = s2.substring(0,s2.length()-1);
s2Letter = s2.charAt(s2.length()-1);
}
int s1Val = Integer.parseInt(newS1);
int s2Val = Integer.parseInt(newS2);
if(s1Val<s2Val)
return -1;
else if(s1Val>s2Val)
return 1;
else if(s1Letter > s2Letter)
return 1;
else if(s1Letter < s2Letter)
return -1;
else
retrurn 0;
}
});
希望有帮助:) 可能有一个更优雅的解决方案,但我相信如果我理解你所面临的问题,这将对你有用
答案 3 :(得分:0)
@bohemian答案很棒,我只做了以下更改,因此几乎可以在任何地方使用。检查数字字符串是因为如果您的输入字符串中没有任何数字,您将收到错误。
Startup.Configure()
请注意,StringUtils来自Program.Main()