java排序混乱的字符串字母和数字排序
- 前言
- 简单说明实现的逻辑
- 适用的字符串类型
- 测试结果
- 测试
- 封装的工具类
- 总结:仰天大笑出门去,我辈岂是蓬蒿人
前言
大概内容:
因为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返回
例如:【#|java排序混乱的字符串字母和数字排序】
你好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 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() {
@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 compareStrList(List stringList) {
//返回对象
List result = new ArrayList<>();
//转Map,并排序字母部分
HashMap> map = getHashMap(stringList);
List sortKey = map.keySet()
.stream()
.sorted()
.collect(Collectors.toList());
for (String key : sortKey) {
List valueList = map.get(key);
valueList.sort(new Comparator() {
@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 findIndexNumberOfStr(String str, String regexp) {
int start = -1;
int end = -1;
Map map = new HashMap<>();
char[] chars = str.toCharArray();
for (int n = 0;
n < chars.length;
n++) {
String value = https://www.it610.com/article/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 strList) {
HashMap> map = new HashMap<>();
for (String str : strList) {
if (StrUtil.isEmpty(str)) continue;
// 截取数字部分的下标,生成key和value值
Map 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 strings = map.get(start);
if (null == strings) {
map.put(start, new ArrayList<>(Arrays.asList(end)));
} else {
strings.add(end);
}
}
return map;
}
}
总结:仰天大笑出门去,我辈岂是蓬蒿人
推荐阅读
- #|java自定义工具类编写规范
- #|AES解密报错,Input length must be multiple of 16 when decrypting with padded cipher
- #|Mybatis的if else妙用(Choose标签使用)
- 框架大集合|【MyBatis详解】——动态SQL解析与执行原理
- java|如何在 ACK 中使用 MSE Ingress
- Redis|Redis实现分布式锁
- spring|springAOP 通过注解实现 日志打印
- java|java基础巩固16
- 抖音|java 抖音开放平台 code token等