背景说明
日常业务中经常会碰到 《3.2.5目录、3.2.10目录》的字符串排序。
根据api进行排序时得到的结果是:
3.2.10目录
3.2.5目录
而实际我们需要的是:
3.2.5目录
3.2.10目录
故需对Comparator接口的compare方法进行重写。
实例
public class FileDemo {
private String name;
public FileDemo(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args){
List<FileDemo> files = new ArrayList<>();
FileDemo file1 = new FileDemo("新华字典1.2.1");
FileDemo file2 = new FileDemo("新华字典1.2.10");
FileDemo file3 = new FileDemo("新华字典1.2.5");
FileDemo file4 = new FileDemo("新华字典1.2.22");
FileDemo file5 = new FileDemo("新华字典1.3.1");
FileDemo file6 = new FileDemo("新华字典1.15.1");
files.add(file1);
files.add(file2);
files.add(file3);
files.add(file4);
files.add(file5);
files.add(file6);
List<FileDemo> collect = files.stream().sorted(Comparator.comparing(FileDemo::getName)).collect(Collectors.toList());
System.out.println(JSONObject.toJSONString(collect));
ComparatorUtil comparatorUtil = new ComparatorUtil();
List<FileDemo> collect1 = (List<FileDemo>)files.stream().sorted(comparatorUtil).collect(Collectors.toList());
System.out.println(JSONObject.toJSONString(collect1));
}
}
//实现Comparator接口,重写compare方法
class ComparatorUtil implements Comparator{
private static Pattern pattern = Pattern.compile("\\d+");
@Override
public int compare(Object o1, Object o2) {
FileDemo file1 = (FileDemo)o1;
FileDemo file2 = (FileDemo)o2;
if(null==file1){
return 1;
}
String name1 = file1.getName();
String name2 = file2.getName();
if(file1 == file2 || name1.equals(name2)){
return 0;
}
if(null == name1){
if(null == name2){
return 0;
} else {
return -1;
}
}else if(null == name2){
return 1;
}
Matcher matcher1 = pattern.matcher(name1);
Matcher matcher2 = pattern.matcher(name2);
int index1_step = 0;
int index2_step = 0;
while(matcher1.find()){
String s1 = matcher1.group();
String s2 = null;
if(matcher2.find()){
s2 = matcher2.group();
int index1 = name1.indexOf(s1, index1_step);
int index2 = name2.indexOf(s2, index2_step);
index1_step = index1;
index2_step = index2;
if(index1 == index2){
String pre1 = name1.substring(0, index1);
String pre2 = name2.substring(0, index2);
if(pre1.equals(pre2)){
long num1 = Long.parseLong(s1);
long num2 = Long.parseLong(s2);
if(num1 == num2){
continue;
}else{
return (int)(num1 - num2);
}
}else{
break;
}
}else{
break;
}
}else{
break;
}
}
return file1.getName().compareTo(file2.getName());
}
}
结果
传统的排序结果:
[
{“name”: “新华字典1.15.1”},
{“name”: “新华字典1.2.1”},
{“name”: “新华字典1.2.10”},
{“name”: “新华字典1.2.22”},
{“name”: “新华字典1.2.5”},
{“name”: “新华字典1.3.1”}
]
重写compare接口的结果
[
{“name”: “新华字典1.2.1”},
{“name”: “新华字典1.2.5”},
{“name”: “新华字典1.2.10”},
{“name”: “新华字典1.2.22”},
{“name”: “新华字典1.3.1”},
{“name”: “新华字典1.15.1”}
]