这个比较器写的
比较好,多种数据形式也能比对排序。
class="java">
package code;
import java.util.*;
public class IntuitiveStringComparator<T extends CharSequence> implements
Comparator<T> {
private T str1, str2;
private int pos1, pos2, len1, len2;
public int compare(T s1, T s2) {
str1 = s1;
str2 = s2;
len1 = str1.length();
len2 = str2.length();
pos1 = pos2 = 0;
if (len1 == 0) {
return len2 == 0 ? 0 : -1;
} else if (len2 == 0) {
return 1;
}
if (isNumeric(str1.toString()) && isNumeric(str2.toString())) {
// System.out.println("test ");
if (Double.parseDouble(str1.toString()) > Double.parseDouble(str2
.toString())) {
return 1;
} else {
return -1;
}
}else {
while (pos1 < len1 && pos2 < len2) {
char ch1 = str1.charAt(pos1);
char ch2 = str2.charAt(pos2);
int result = 0;
if (Character.isDigit(ch1)) {
result = Character.isDigit(ch2) ? compareNumbers() : -1;
} else if (Character.isLetter(ch1)) {
result = Character.isLetter(ch2) ? compareOther(true) : 1;
} else {
result = Character.isDigit(ch2) ? 1 : Character
.isLetter(ch2) ? -1 : compareOther(false);
}
if (result != 0) {
return result;
}
}
}
return len1 - len2;
}
private int compareNumbers() {
int delta = 0;
int zeroes1 = 0, zeroes2 = 0;
char ch1 = (char) 0, ch2 = (char) 0;
// Skip leading zeroes, but keep a count of them.
while (pos1 < len1 && (ch1 = str1.charAt(pos1++)) == '0') {
zeroes1++;
}
while (pos2 < len2 && (ch2 = str2.charAt(pos2++)) == '0') {
zeroes2++;
}
// If one sequence contains more significant digits than the
// other, it's a larger number. In case they turn out to have
// equal lengths, we compare digits at each position; the first
// unequal pair determines which is the bigger number.
while (true) {
boolean noMoreDigits1 = (ch1 == 0) || !Character.isDigit(ch1);
boolean noMoreDigits2 = (ch2 == 0) || !Character.isDigit(ch2);
if (noMoreDigits1 && noMoreDigits2) {
return delta != 0 ? delta : zeroes1 - zeroes2;
} else if (noMoreDigits1) {
return -1;
} else if (noMoreDigits2) {
return 1;
} else if (delta == 0 && ch1 != ch2) {
delta = ch1 - ch2;
}
ch1 = pos1 < len1 ? str1.charAt(pos1++) : (char) 0;
ch2 = pos2 < len2 ? str2.charAt(pos2++) : (char) 0;
}
}
private int compareOther(boolean isLetters) {
char ch1 = str1.charAt(pos1++);
char ch2 = str2.charAt(pos2++);
if (ch1 == ch2) {
return 0;
}
if (isLetters) {
ch1 = Character.toUpperCase(ch1);
ch2 = Character.toUpperCase(ch2);
if (ch1 != ch2) {
ch1 = Character.toLowerCase(ch1);
ch2 = Character.toLowerCase(ch2);
}
}
return ch1 - ch2;
}
public boolean isNumeric(String str12) {
// String str12 = str1.toString();
try {
double d = Double.parseDouble(str12);
} catch (NumberFormatException nfe) {
return false;
}
return true;
// return str12.matches("-?\\d+(\\.\\d+)?"); //match a number with
// optional '-' and decimal.
}
public static void main(String[] args) {
String[] list = { "foo 03", "foo 00003", "foo 5", "foo 003", "foo~03",
"foo 10far", "foo 10boo", "2", "0.5", "foo 10", "-20", "1.1", "foo!03",
"1.0", "10000", "20", ".7","-40"
};
Arrays.sort(list, new IntuitiveStringComparator<String>());
for (String s : list) {
System.out.println(s);
}
}
}
运行结果如下:
-40
-20
0.5
.7
1.0
1.1
2
20
10000
foo 03
foo 003
foo 00003
foo 5
foo 10
foo 10far
foo 10boo
foo!03
foo~03
即使小数点前没有零也能正常排序。
- IntuitiveStringComparator.7z (1.4 KB)
- 下载次数: 0