1、因为在工作中需要做一个排序,但是排序中涉及的排序规则又比较复杂,单用hutool的拼音排序(PinyinComparator)和版本排序(VersionComparator)又达不到我的要求,所以写了个集合这两种排序规则的排序方法类,方法主体是另一位大佬开源的一篇文章,我又做了一些修改,但是等我记录的时候,已经找不到那篇文章的链接了,如果有哪位看到原文了,可以联系我附上原文链接;大家可以先看下面截图,看是否符合自己排序要求再拿去使用测试吧;如果本篇文章有哪里有误的地方,欢迎各位大佬进行指正;如果有哪位大佬有更好的优化思路,可以将您的思路留在评论区,让我学习学习;
2、排序效果截图:
3、主要用到的开源框架是:hutool
4、源码如下:
import cn.hutool.core.comparator.PinyinComparator;
import cn.hutool.core.util.CharUtil;
import java.io.Serializable;
import java.util.Comparator;
/**
* 汉字拼音加版本排序
*
* @since 2023/10/09 18:39
*/
public class MyPinyinComparator implements Comparator<String>, Serializable {
private static final long serialVersionUID = 7520224992810502033L;
private String str1, str2;
private int pos1, pos2, len1, len2;
/**
* 单例
*/
public static final MyPinyinComparator INSTANCE = new MyPinyinComparator();
/**
* 默认构造
*/
public MyPinyinComparator() {
}
@Override
public int compare(String o1, String o2) {
str1 = o1;
str2 = o2;
len1 = str1.length();
len2 = str2.length();
pos1 = pos2 = 0;
int result = 0;
while (result == 0 && pos1 < len1 && pos2 < len2) {
char ch1 = str1.charAt(pos1);
char ch2 = str2.charAt(pos2);
if (CharUtil.isNumber(ch1)) {
result = CharUtil.isNumber(ch2) ? compareNumbers() : -1;
} else if (CharUtil.isLetter(ch1)) {
result = CharUtil.isLetter(ch2) ? compareOther(true) : 1;
} else {
result = CharUtil.isNumber(ch2) ? 1
: CharUtil.isLetter(ch2) ? -1
: compareOther(false);
}
pos1++;
pos2++;
}
return result == 0 ? len1 - len2 : result;
}
private int compareNumbers() {
int end1 = pos1 + 1;
while (end1 < len1 && CharUtil.isNumber(str1.charAt(end1))) {
end1++;
}
int fullLen1 = end1 - pos1;
while (pos1 < end1 && str1.charAt(pos1) == '0') {
pos1++;
}
int end2 = pos2 + 1;
while (end2 < len2 && CharUtil.isNumber(str2.charAt(end2))) {
end2++;
}
int fullLen2 = end2 - pos2;
while (pos2 < end2 && str2.charAt(pos2) == '0') {
pos2++;
}
int delta = (end1 - pos1) - (end2 - pos2);
if (delta != 0) {
return delta;
}
while (pos1 < end1 && pos2 < end2) {
delta = str1.charAt(pos1++) - str2.charAt(pos2++);
if (delta != 0) {
return delta;
}
}
pos1--;
pos2--;
return fullLen2 - fullLen1;
}
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 new PinyinComparator().compare(String.valueOf(ch1), String.valueOf(ch2));
}
}