项目场景:
在项目中做一个报表时需要对编码排序,按照编码序号排序展示
问题描述:
在数据库中按照编码排序超过10之后得排序会出现问题,比如:10.10会出现在10.9之前。
public static void main(String[] args) {
// 初始化目录编码数组
String[] sortString = {"7.1", "6.4", "5.1", "5.1.6.12", "5.1.6.3", "6.3", "10.1.1.6", "5.1.1", "10.9.1", "5.1.6.10",
"5.1.6", "10.4", "5.1.5", "5.1.6.8", "10.1.2", "5.1.6.6", "6.2", "5.1.8", "5.1.6.13", "5.1.6.2", "6.5",
"10.9.3", "6", "10", "10.9.2", "10.1.1", "10.1.1.1", "10.1.4", "10.9.4", "5.1.2.1", "5.1.2.2",
"5.2.3", "5.1.6.11", "8.9", "5.1.6.7", "10.1.1.2", "10.1", "10.10", "8.6", "7.2", "10.10.2",
"10.10.3", "10.10.1", "10.10.4", "11", "5.1.7", "12", "10.9.5", "10.9", "8.11", "8.1",
"8", "7", "8.8", "5.1.6.1", "5.1.6.9", "5.1.1.3", "5.1.1.1", "5.1.3", "5.1.2", "5.1.1.2",
"10.3", "5.1.4"};
List<String> sort = Arrays.asList(sortString);
// 打印初始化内容
AtomicInteger j = new AtomicInteger(0);
sort.forEach(item -> {
i.getAndIncrement();
System.out.print(item);
if (i.get() != sortString.length) {
System.out.print(" -> ");
}
if (i.get() % 10 == 0) {
System.out.println();
}
});
System.out.println();
}
原因分析:
由于在数据库中对编码进行了排序,在代码层面上只做了末尾排序,这个排序只针对同级有效,所以在出现与其父级同级的编码时会出现无法排序的情况,所以要优化这个排序的算法。
private void sortByConfigCode(List<String> result) {
result.sort((o1, o2) -> {
int o1Length = o1.split("\\.").length;
int o2Length = o2.split("\\.").length;
String o1SubStr = o1Length == 1 ? o1 : o1.substring(0, o1.lastIndexOf("."));
String o2SubStr = o2Length == 1 ? o2 : o2.substring(0, o2.lastIndexOf("."));
if (o1Length == o2Length && o1SubStr.equals(o2SubStr)) {
return Integer.parseInt(o1.split("\\.")[o1Length - 1]) - Integer.parseInt(o2.split("\\.")[o2Length - 1]);
}
return 0;
});
}
解决方案:
1、首先将对比的两个字符串切割成字符串数组
2、对比两个字符串数据的长度,用短的作为循环判断的依据
3、遍历字符串数组,同下标下的相等的跳过,不相等时判断大小
4、遍历完匹配不到不相等的,说明短字串属于长字串的一部分,即短字段为长字段的父级,比较两字符串数组的容量。
5、算法完成
// 目录编码排序核心
sort.sort((o1, o2) -> {
String[] o1Arr = o1.split("\\.");
String[] o2Arr = o2.split("\\.");
int length = Math.min(o1Arr.length, o2Arr.length);
for (int n = 0; n < length; n++) {
if (Integer.parseInt(o1Arr[n]) != Integer.parseInt(o2Arr[n])) {
return Integer.parseInt(o1Arr[n]) - Integer.parseInt(o2Arr[n]);
}
}
return o1Arr.length - o2Arr.length;
});
效果如下:
2023年04月04日补充方案:
排序在每个层级中多冗余一个字段为排序号,即无需做切割字符串的操作,排序只需对同级排序号进行排序即可