我有以下可能的地址作为字符串(未排序):
"road 21"
"road 1"
"road 186"
"road +21 / 23"
"road +21 / 19"
"another road 21"
"another road 1"
我希望能够将它们排序为(所以不是默认的String排序方式):
another road 1
another road 21
road 1
road 21
road +21 / 19
road +21 / 23
road 186
我该怎么做?我可能不得不使用自定义比较器,但是我应该如何拆分String?
答案 0 :(得分:3)
我用Java实现了这个,我知道它起初看起来很奇怪。
如果您有任何问题请随时问我
public class SpecialComparator implements Comparator<String> {
@Override
public int compare(String arg0, String arg1) {
// TODO Auto-generated method stub
String []words1=arg0.split(" ");
String [] words2 = arg1.split(" ");
int i = 0;
if (words1[i].hashCode()>words2[i].hashCode()){
return 1;
}
else if (words1[i].hashCode()<words2[i].hashCode()){
return -1;
}
else if (words1[i].hashCode()==words2[i].hashCode())
return compare(arg0.substring(i+1, arg0.length()), arg1.substring(i+1,arg1.length()));
else if (i == Math.min(words1.length,words2.length)-1 && Math.min(words1.length,words2.length) == words1.length){
return -1;
}
else if (i == Math.min(words1.length,words2.length)-1 && Math.min(words1.length,words2.length) == words2.length){
return 1;
}
else if (i == Math.min(words1.length,words2.length)-1 && words1.length == words2.length){
return 0;
}
else{
return 0;
}
}
public static void main (String[] args){
ArrayList<String> input = new ArrayList<String>();
SpecialComparator a = new SpecialComparator();
input.add("road 21");
input.add("road 1");
input.add("road 186");
input.add("road +21 / 23");
input.add("road +21 / 19");
input.add("another road 21");
input.add("another road 1");
Collections.sort(input,a);
for (String ans : input){
System.out.println(ans);
}
}
}
答案 1 :(得分:1)
您的格式似乎是:
因此,我会使用这些属性创建一个表示此格式的对象:
public class MyInput {
private String name;
private Integer firstNumber;
private Integer secondNumber;
}
然后解析输入文件以创建List<MyInput>
。
最后,您创建自定义Comparator
可以调用Collections.sort(yourList, yourCustomComparator)
答案 2 :(得分:0)
这个问题似乎很多。我一直在使用Martin Pools NaturalOrderCompartor。您可以轻松地将其移植到您的代码中。
https://github.com/paour/natorder/blob/master/NaturalOrderComparator.java
答案 3 :(得分:0)
它有点讨厌,但这是我解决你问题的方法
List<String> list = Arrays.asList("road 21", "road 1", "road 186",
"road +21 / 23", "road +21 / 19", "another road 21",
"another road 1");
Collections.sort(list, new Comparator<String>() {
Integer toNumber(String string) {
try {
return Integer.parseInt(string);
} catch (NumberFormatException e) {
return null;
}
}
@Override
public int compare(String o1, String o2) {
String[] left = o1.split("\\s+");
String[] right = o2.split("\\s+");
for (int i = 0; i < Math.min(left.length, right.length); i++) {
String ls = left[i];
String rs = right[i];
Integer li = toNumber(ls);
Integer ri = toNumber(rs);
if (li != null && ri != null
&& li.intValue() != ri.intValue()) {
return li.intValue() - ri.intValue();
} else if (li != null && ri == null) {
return 1;
} else if (li == null && ri != null) {
return -1;
} else if (li == null && ri == null){
int compared = ls.compareToIgnoreCase(rs);
if (compared != 0) {
return compared;
}
}
}
return left.length - right.length;
}
});
但是如果您可以改变您的结构,那么请使用Arnaud Denoyelle提出的解决方案
答案 4 :(得分:0)
您也可以尝试使用比较器:
class MyComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
o1 = o1.replace("+", "");
o2 = o2.replace("+", "");
String[] a1 = o1.split(" ");
String[] a2 = o2.split(" ");
int length = (a1.length > a2.length) ? a2.length : a1.length;
for (int i = 0; i < length; i++) {
if (!a1[i].equalsIgnoreCase(a2[i])) {
if (!isIntegerRegex(a1[i]) || !isIntegerRegex(a2[i])) {
return o1.compareTo(o2);
}
int f = Integer.parseInt(a1[i]);
int s = Integer.parseInt(a2[i]);
return f - s;
}
}
return a1.length - a2.length;
}
public boolean isIntegerRegex(String str) {
return str.matches("^[0-9]+$");
}
}
并称之为:
public String[] sortStrings(String[] input) {
Arrays.sort(input, new MyComparator());
return input;
}