大概内容:
因为java默认的自然排序算法,会把G2, G1, G11, G9,G16, G4排序成G1, G11, G16, G2, G4, G9,针对这种情况我封装了一个工具类,排序后得到的是G1, G2 , G4, G9, G11, G16;
就是把List先根据字符串
字母部分分组,得到一个Map
,对每个map的元素的数字部分数组排序,排序后拼接还原成List返回>也可以说是Map<字母部分,List<数字部分>>
例如:
你好1,你好2,我好3 //先根据汉字的音法排序,再根据数字排序
A1,wAD1,A2,a1,h1,W1,W3 // 先根据字母顺序排序,再根据数字部分排序
A1-1,a2-3,V1-1,A2-1 //先根据字母排序,然后根据-前面的数字排序,再根据-后面的数字排序,-可以为任意符号
提示:以下是本篇文章正文内容,下面案例可供参考
原始数据:[GXC(WS)2-2, GXC(WS)1-3, GXC(WS)1-1, GXC(GS)2, GXC(WS)2-1, GXC(GS)1, GXC(GS)17-1, GXC(GS)8, GXC(GS)6, GXC(GS)6, GXC(GS)2, ]
自然排序:[, GXC(GS)1, GXC(GS)17-1, GXC(GS)2, GXC(GS)2, GXC(GS)6, GXC(GS)6, GXC(GS)8, GXC(WS)1-1, GXC(WS)1-3, GXC(WS)2-1, GXC(WS)2-2]
调用工具类排序:[GXC(GS)1, GXC(GS)2, GXC(GS)2, GXC(GS)6, GXC(GS)6, GXC(GS)8, GXC(GS)17-1, GXC(WS)1-1, GXC(WS)1-3, GXC(WS)2-1, GXC(WS)2-2]
public static void main(String[] args) {
//原始数据
ArrayList<String> objects = new ArrayList<>();
objects.add("GXC(WS)2-2");
objects.add("GXC(WS)1-3");
objects.add("GXC(WS)1-1");
objects.add("GXC(GS)2");
objects.add("GXC(WS)2-1");
objects.add("GXC(GS)1");
objects.add("GXC(GS)17-1");
objects.add("GXC(GS)8");
objects.add("GXC(GS)6");
objects.add("GXC(GS)6");
objects.add("GXC(GS)2");
objects.add("");
System.err.println("原始数据:"+objects);
//自然排序
objects.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
System.err.println("自然排序:"+objects);
System.err.println("调用工具类排序:"+compareStrList(objects));
}
import cn.hutool.core.util.StrUtil;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Description: 测点排序工具类
* @Param:
* @return:
* @Author: 杨永卓
* @Date: 2022年7月13日09:53:493
*/
public class PointSortUtil {
//正负数小数正则表达式
private static final String REGEX_NUM = "^[-\\+]?([0-9]+\\.?)?[0-9]+$";
//自定义字符格式
private static final String CHAR_TYPE = "-";
/**
* @Description: 对List混合字符串排序
* @Param: o1:对list混合字符串排序,o2:对list混合字符串排序 例如:SDD1-1/SDD1
* @return: 1大于 0等于 -1小于
* @Author: 杨永卓
* @Date: 2022年7月18日14:32:44
*/
public static List<String> compareStrList(List<String> stringList) {
//返回对象
List<String> result = new ArrayList<>();
//转Map,并排序字母部分
HashMap<String, List<String>> map = getHashMap(stringList);
List<String> sortKey = map.keySet()
.stream()
.sorted()
.collect(Collectors.toList());
for (String key : sortKey) {
List<String> valueList = map.get(key);
valueList.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
String[] split1 = o1.split(CHAR_TYPE);
String[] split2 = o2.split(CHAR_TYPE);
if (!getValueIsNumber(split1[0]) || !getValueIsNumber(split2[0])) {
return -1;
}
// 排序
if (Integer.parseInt(split1[0]) > Integer.parseInt(split2[0])) {
return 1;
} else if (Integer.parseInt(split1[0]) == Integer.parseInt(split2[0])) {
if (split1.length == 2 && split2.length == 2) {
if (Integer.parseInt(split1[1]) > Integer.parseInt(split2[1])) {
return 1;
} else if (Integer.parseInt(split1[1]) == Integer.parseInt(split2[1])) {
return 0;
}
return -1;
}
return 0;
}
return -1;
}
});
for (String value : valueList) {
result.add(key + value);
}
}
return result;
}
/**
* 查询字符串中正则筛选后第一次出现和最后一次出现的下标
*
* @param str 查询的字符串,status:0起始下标 1结束下标 ,regexp:正则
* @return 若存在,返回位置索引,否则返回-1;
* 杨永卓
* 2022年7月13日09:57:36
*/
private static Map<String, Integer> findIndexNumberOfStr(String str, String regexp) {
int start = -1;
int end = -1;
Map<String, Integer> map = new HashMap<>();
char[] chars = str.toCharArray();
for (int n = 0; n < chars.length; n++) {
String value = String.valueOf(chars[n]);
boolean b = value.matches(regexp);
if (b) {
if (start > -1) {
end = n;
} else {
start = n;
end = n;
}
} else {
if (start > -1) {
map.put("startIndex", start);
map.put("endIndex", end);
// return map;
}
}
}
map.put("startIndex", start);
map.put("endIndex", end);
return map;
}
/**
* 2022年7月13日09:57:30
* 杨永卓
* 判断字符串是否为纯数字
*/
private static boolean getValueIsNumber(String thisValue) {
if (StrUtil.isEmpty(thisValue)) return false;
return thisValue.matches(REGEX_NUM);
}
/**
* @Description: 把字符串数组拆解转为HashMap返回
* @Param:
* @return:
* @Author: 杨永卓
* @Date: 2022/7/18 14:09
*/
private static HashMap getHashMap(List<String> strList) {
HashMap<String, List<String>> map = new HashMap<>();
for (String str : strList) {
if (StrUtil.isEmpty(str)) continue;
// 截取数字部分的下标,生成key和value值
Map<String, Integer> map1 = findIndexNumberOfStr(str, "^[0-9]+$");
String start = str.substring(0, map1.get("startIndex"));
String end = str.substring(map1.get("startIndex"), map1.get("endIndex") + 1);
List<String> strings = map.get(start);
if (null == strings) {
map.put(start, new ArrayList<>(Arrays.asList(end)));
} else {
strings.add(end);
}
}
return map;
}
}