Java 大写字母流水号递增

233 阅读1分钟

一、大写字母流水号递增

源码:

/**
 * 流水号工具类
 *
 * @author CCG
 * @date 2022/12/8
 * @description
 */
public class SerialNumberUtil {

    private static final Pattern pattern = Pattern.compile("[0-9]*");

    private static final StringBuffer strJoint = new StringBuffer();

    /**
     * @param prefix 前缀
     * @param code   字母流水号
     * @param len    位数
     * @return
     */
    public static final synchronized String getNextUppercaseSerialNumber(String prefix, String code, int len) {
        String str = getNextUppercaseSerialNumber(code, len);
        strJoint.setLength(0);
        return strJoint.append(prefix).append(str).toString();
    }

    /**
     * 大写字母流水号递增
     * * 字母前缀 + 数字位 = 4位,
     * * 数字位全为9 进一位字母
     * * 最大支持 0001 ~ ZZZZ -> 717948
     *
     * @param code
     * @param len
     * @return
     */
    public static final synchronized String getNextUppercaseSerialNumber(String code, int len) {
        if (code.length() > len) {
            throw new RuntimeException("流水号位数已经超" + len);
        }
        strJoint.setLength(0);
        // 纯数字
        if (isNumeric(code)) {
            strJoint.append(getConvertNum(Integer.valueOf(code) + 1, 4));
            // 超出长度限制,默认A00..1开始
            if (strJoint.length() > len) {
                strJoint.setLength(0);
                strJoint.append("A").append(getRepeatCode("0", len - 2)).append("1");
            }
            return strJoint.toString();
        }
        if (code.equals(getRepeatCode("Z", len))) {
            return code;
        }
        // 取字母前缀,数字后缀
        String prefix = getUppercasePrefix(code);
        // 前缀字母位相同,字母递增
        if (prefix.length() == len) {
            prefix = getNextUppercase(prefix, len);
            return prefix;
        }
        String suffix = code.substring(code.lastIndexOf(prefix) + prefix.length());
        // 数字位全为9,字母进一位,
        if (suffix.equals(getRepeatCode("9", suffix.length()))) {
            // 特性处理,Y999 -> Z001
            if (prefix.length() == 1 && prefix.equals("Y")) {
                strJoint.setLength(0);
                strJoint.append("Z").append(getRepeatCode("0", len - prefix.length() - 1)).append("1");
                return strJoint.toString();
            }
            prefix = getNextUppercase(prefix, len);
            if (prefix.length() == len) {
                return prefix;
            }
            strJoint.setLength(0);
            strJoint.append(prefix).append(getRepeatCode("0", len - prefix.length() - 1)).append("1");
            return strJoint.toString();
        }
        // 递增
        strJoint.setLength(0);
        strJoint.append(prefix).append(getConvertNum(Integer.parseInt(suffix) + 1, suffix.length()));

        return strJoint.toString();
    }

    /**
     * 字母递增
     *
     * @param prefix
     * @return
     */
    public static final synchronized String getNextUppercase(String prefix, int len) {
        char[] chars = prefix.toCharArray();
        prefix = String.valueOf(getNextChar(chars, chars.length - 1));
        // 新增一位字母
        if (prefix.length() < len && prefix.equals(getRepeatCode("Z", prefix.length()))) {
            strJoint.setLength(0);
            strJoint.append(getRepeatCode("A", prefix.length() + 1));

            return strJoint.toString();
        }

        return prefix;
    }

    /**
     * 字母位数递增
     *
     * @param chars
     * @param index
     * @return
     */
    public static final char[] getNextChar(char[] chars, int index) {
        // 首位已经是Z,无法递增,直接访问
        if (0 == index && "Z".equals(String.valueOf(chars[0]))) {
            return chars;
        }
        // 下标位是Z,上移一位,当前变为A
        if ("Z".equals(String.valueOf(chars[index]))) {
            // 字母A
            char last = (char) (chars[index] - 25);
            chars[index] = last;
            return getNextChar(chars, index - 1);
        }
        // 字母递增
        char last = (char) (chars[index] + 1);
        chars[index] = last;
        return chars;
    }

    /**
     * 获取重复位数
     *
     * @param s
     * @param len
     * @return
     */
    public static final String getRepeatCode(String s, int len) {
        return String.join(StrUtil.EMPTY, Collections.nCopies(len, s));
    }

    /**
     * 位数补全
     *
     * @param num
     * @param len
     * @return
     */
    public static final String getConvertNum(int num, int len) {
        return String.format("%0" + len + "d", num);
    }

    /**
     * 判断数字格式
     *
     * @param str
     * @return
     */
    public static final boolean isNumeric(String str) {
        return pattern.matcher(str).matches();
    }

    /**
     * 获取大写字母前缀
     *
     * @param str
     * @return
     */
    public static final String getUppercasePrefix(String str) {
        return str.replaceAll("\s*", "").replaceAll("[^(A-Z)]", "");
    }


    public static void main(String[] args) {

        Set<String> list = new HashSet<>();
        String code = "0";

        try (FileOutputStream fileOutputStream = new FileOutputStream(new File("d:/case.txt"))) {
            for (int i = 0; i < 1000000; i++) {
                code = getNextUppercaseSerialNumber(code, 4);
                if (!list.add(code)) {
                    throw new RuntimeException(String.format("已存在:Code=%s,Index=%s \r\n", code, i));
                }
                String msg = String.format("Code=%s,Index=%s \r\n", code, i);
                fileOutputStream.write(msg.getBytes());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}