Java先根据字符串的首字母排序,再根据数字部分排序



前言

java项目对于对象的混合字符串例如:[a4, a4, b2, B3, a7, b3, A1, a1, a3, B2, A2, b1, a2, B1]排序,会出现A1,A13,A15,A2,A24这样的排序混乱情况,下面是我封装的工具类根据数字部分进行排序,可以直接拿走使用,排序后[A1, A2, B1, B2, B3, a1, a2, a3, a4, a4, a7, b1, b2, b3],如果是要先根据字母排序再根据数字排序,也很简单,下面第二个就是


提示:以下是本篇文章正文内容,下面案例可供参考

工具类代码


import cn.hutool.core.util.StrUtil;

import java.util.*;


/**
 * @Description: 测点排序工具类
 * @Param:
 * @return:
 * @Author: 杨永卓
 * @Date: 2022年7月13日09:53:493
 */
public class PointSortUtil {
    //正负数小数正则表达式
    private static final String REGEX_NUM = "^[-\\+]?([0-9]+\\.?)?[0-9]+$";

    /**
     * @Description: 用来对两个混合数字排序
     * @Param: o1混合数字   o2混合数字
     * @return: 1大于      0等于    -1小于
     * @Author: 杨永卓
     * @Date: 2022/7/13 15:26
     */
    public static int compare(String o1, String o2) {
        if (StrUtil.isEmpty(o1)) {
            return -1;
        } else if (StrUtil.isEmpty(o2)) {
            return 1;
        } else if (StrUtil.isEmpty(o1) && StrUtil.isEmpty(o2)) {
            return -1;
        }

//                      截取线路数字部分的下标
        Map<String, Integer> map1 = findIndexNumberOfStr(o1, "^[0-9]+$");
        Map<String, Integer> map2 = findIndexNumberOfStr(o2, "^[0-9]+$");
        if (-1 == map1.get("startIndex") || -1 == map1.get("endIndex") || -1 == map2.get("startIndex") || -1 == map2.get("endIndex")) {
            return -1;
        }
//                      转换字符串
        String str1 = o1.substring(map1.get("startIndex"), map1.get("endIndex") + 1);
        String str2 = o2.substring(map2.get("startIndex"), map2.get("endIndex") + 1);
        if (!getValueIsNumber(str1) || !getValueIsNumber(str2)) {
            return -1;
        }
//                      排序
        if (Integer.parseInt(str1) > Integer.parseInt(str2)) {
            return 1;
        } else if (Integer.parseInt(str1) == Integer.parseInt(str2)) {
            return 0;
        }
        return -1;
    }

	 /**
     * @Description: 用来对两个混合数字的首字母排序
     * @Param: o1混合数字   o2混合数字
     * @return: 1大于      0等于    -1小于
     * @Author: 杨永卓
     * @Date: 2022/7/13 15:26
     */
    public static int compareChar(String o1, String o2) {
        if(o1.charAt(0)>o2.charAt(0)) return 1;
        else if(o1.charAt(0)==o2.charAt(0)) return 0;
        else return -1;
    }


    /**
     * 查询字符串中正则筛选后第一次出现和最后一次出现的下标
     *
     * @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 {
//              如果线路为  S1号线1  S1号线2  则取中间的数字并返回
                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);
    }

}

业务层调用

一、只根据字符串的数字部分排序,业务层调用

List<User> users=new ArrayList();
//如果测项名称相同就手动排序
if(users.size()>0){
    String itemName = users.get(0).getItemName();
    if("中文".equals(itemName)||"汉语".equals(itemName)){
        users.sort(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
            	//这里调用工具类实现排序
                return PointSortUtil.compare(o1.getPointName(),o2.getPointName());
            }
        });
    }
}

二、先根据字符串的首字母排序,再根据数字部分排序

List<User> users=new ArrayList();
//如果测项名称相同就手动排序
if(users.size()>0){
    String itemName = users.get(0).getItemName();
    if("中文".equals(itemName)||"汉语".equals(itemName)){
        users.sort(new Comparator<User>() {
            @Override
            public int compare(User o1, Usero2) {
                return PointSortUtil.compareChar(o1.getName(),o2.getName());
            }
        }.thenComparing(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return PointSortUtil.compare(o1.getName(),o2.getName());
            }
        }))
    }
}


总结:仰天大笑出门去,我辈岂是蓬蒿人

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT行业小趴菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值