這次項目中碰到這樣一個問題:對一個亂序的字符串集合進行排序,字符串集合包含以下內容
"1"、"1.1"、"1.3"、"1.9"、"1.7"、"1.10.1、"1.10"、"1.2"、"1.4"、"1.5"、"1.8"、"1.6"、"1.11"、"2.4"、"2.10"、"1.1.10"、
"1.1.8"、"2.1.3"、"2.1.5"、"2.1.10"
使用集合默認的排序功能,結果是這樣的
"1"、"1.1"、"1.1.10"、"1.1.8"、"1.10"、"1.10.1"、"1.11"、"1.2"、"1.3"、"1.4"、"1.5"、"1.6"、"1.7"、"1.8"、"1.9"、
"2.1.10"、"2.1.3"、"2.1.5"、" 2.10"、"2.4"
可以看到"1.10"、"1.1.10"、"2.1.10"等字符串的排序是不符合預期的,所以我手動寫了一個比較器解決該問題。
具體實現如下:
public class StringComparator implements Comparator<String> {
private final int ToRight = 1;
private final int ToLeft = -1;
@Override
public int compare(String str1, String str2) {
String[] str1Split = str1.split("\\.");
String[] str2Split = str2.split("\\.");
int minSplitLength = str1Split.length > str2Split.length
? str2Split.length : str1Split.length;
// 用長度小的數組長度作爲遍歷邊界,防止數組越界
for (int i = 0; i < minSplitLength; i++) {
// 將字符串轉換成數字解決 一位數字(eg: 2) 和 兩位數字(eg: 10) 的大小比較問題
Integer strToInt1 = Integer.valueOf(str1Split[i]);
Integer strToInt2 = Integer.valueOf(str2Split[i]);
int compareResult = strToInt1.compareTo(strToInt2);
if (compareResult == 0) {
continue;
} else if (compareResult > 0) {
return ToRight;
} else if (compareResult < 0) {
return ToLeft;
}
}
// 若程序進行到這裏,說明在循環裏沒有得出比較結果。
// 此時應該是數組長度長的字符串(1.10.1)排在後面,數組長度短的字符串(1.10)排在前面
if (minSplitLength == str1Split.length) {
return ToLeft;
} else {
return ToRight;
}
}
public static void main(String[] args) {
String[] dataSource = new String[] {"1","1.1","1.3","1.9","1.7","1.10.1","1.10",
"1.2","1.4","1.5", "1.8","1.6","1.11","2.4","2.10","1.1.10","1.1.8",
"2.1.3","2.1.5","2.1.10","2"};
List<String> data = new ArrayList<>(Arrays.asList(dataSource));
System.out.println("original data: " + data);
TreeSet<String> stringComparator = new TreeSet<>(new StringComparator());
// 數據排序
stringComparator.addAll(data);
// 將排序完成的數據放回原集合
data.clear();
data.addAll(stringComparator);
System.out.println("sorted data: " + data);
}
}
打印結果如下:
original data: [1, 1.1, 1.3, 1.9, 1.7, 1.10.1, 1.10, 1.2, 1.4, 1.5, 1.8, 1.6, 1.11, 2.4, 2.10, 1.1.10, 1.1.8, 2.1.3, 2.1.5, 2.1.10, 2]
sorted data: [1, 1.1, 1.1.8, 1.1.10, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.10.1, 1.11, 2, 2.1.3, 2.1.5, 2.1.10, 2.4, 2.10]