java实现(燃油车车牌生成)

简介: java实现(燃油车车牌生成)

暗箱

车牌中有很多个规则,还有很多暗箱,我们随机生成试试水。

首先定义一些特殊字母,例如I和O不会出现在车牌中,因为他跟1个0不容易区分。

再者添加一些我们认为比较好的车牌,这些车牌在随机生成的车牌里面肯定不会出现。

比如说顺子54321,炸弹号66666,特殊意义的谐音74110等等,都是暗箱,懂得都懂。

你说什么:运气好肯定还是可以随机出来的,没有随机出来,是因为你运气不好。

我只能说:感谢这个社会还有像你这样天真的人,继续保持。

厄运小姐:“好运不会眷顾傻瓜”

废话不对说,上代码

常量车牌+特殊车牌

 
import java.util.*;
 
/**
 * 常量(车牌)
 */
public final class VehicleConstants {
 
    public static final String[] STR_AZ_NICE = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", /*"I",*/ "J", "K", "L", "M", "N", /*"O",*/ "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
    public static final String[] STR_AZ = {"A", "B", "C", "D", "E", "F", "G", "H", /*"I", */"J", "K", "L", "M", "N", /*"O",*/ "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
    public static final String[] STR_ZERO_NICE = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
    public static final String STR_I = "I", STR_O = "O", STR_SYS = "*";
    /**
     * 判断字母是否包含I或者O
     */
    public static final List<String> LIST_IO = Arrays.asList(new String[]{"I", "O"});
    /**
     * 河南地区对应字母
     */
    public static final Map<String, String> YU_AREA_MAP = new HashMap();
    /**
     * 苏州地区对应字母
     */
    public static final Map<String, String> SU_AREA_MAP = new HashMap();
    /**
     * 炸弹车牌
     */
    public static final Map<String, String> VEHICLE_BOMB_MAP = new HashMap();
    /**
     * 顺子车牌-倒序
     */
    public static final Map<String, String> VEHICLE_STRAIGHT_DESC_MAP = new HashMap();
    /**
     * 顺子车牌-正序
     */
    public static final Map<String, String> VEHICLE_STRAIGHT_ASC_MAP = new HashMap();
    /**
     * 敏感车牌集合(可以添加你认为的敏感车牌)
     */
    public static final List<String> VEHICLE_SENSITIVE_LIST = new ArrayList<>();
 
    static {
        VEHICLE_SENSITIVE_LIST.add("1992");
        VEHICLE_SENSITIVE_LIST.add("1994");
        VEHICLE_SENSITIVE_LIST.add("2000");
        VEHICLE_SENSITIVE_LIST.add("2003");
 
        VEHICLE_SENSITIVE_LIST.add("520");
        VEHICLE_SENSITIVE_LIST.add("521");
        VEHICLE_SENSITIVE_LIST.add("1314");
 
        VEHICLE_SENSITIVE_LIST.add("000");
        VEHICLE_SENSITIVE_LIST.add("0000");
        VEHICLE_SENSITIVE_LIST.add("111");
        VEHICLE_SENSITIVE_LIST.add("1111");
        VEHICLE_SENSITIVE_LIST.add("222");
        VEHICLE_SENSITIVE_LIST.add("2222");
        VEHICLE_SENSITIVE_LIST.add("333");
        VEHICLE_SENSITIVE_LIST.add("3333");
        VEHICLE_SENSITIVE_LIST.add("444");
        VEHICLE_SENSITIVE_LIST.add("4444");
        VEHICLE_SENSITIVE_LIST.add("555");
        VEHICLE_SENSITIVE_LIST.add("5555");
        VEHICLE_SENSITIVE_LIST.add("666");
        VEHICLE_SENSITIVE_LIST.add("6666");
        VEHICLE_SENSITIVE_LIST.add("777");
        VEHICLE_SENSITIVE_LIST.add("7777");
        VEHICLE_SENSITIVE_LIST.add("888");
        VEHICLE_SENSITIVE_LIST.add("8888");
        VEHICLE_SENSITIVE_LIST.add("999");
        VEHICLE_SENSITIVE_LIST.add("9999");
 
        VEHICLE_SENSITIVE_LIST.add("74110");
        VEHICLE_SENSITIVE_LIST.add("74120");
        VEHICLE_SENSITIVE_LIST.add("74119");
        VEHICLE_SENSITIVE_LIST.add("00544");
        VEHICLE_SENSITIVE_LIST.add("44944");
        VEHICLE_SENSITIVE_LIST.add("12580");
 
        VEHICLE_BOMB_MAP.put("VIP-A", "11111");
        VEHICLE_BOMB_MAP.put("VIP-B", "22222");
        VEHICLE_BOMB_MAP.put("VIP-C", "33333");
        VEHICLE_BOMB_MAP.put("VIP-D", "44444");
        VEHICLE_BOMB_MAP.put("VIP-E", "55555");
        VEHICLE_BOMB_MAP.put("VIP-F", "66666");
        VEHICLE_BOMB_MAP.put("VIP-G", "77777");
        VEHICLE_BOMB_MAP.put("VIP-H", "88888");
        VEHICLE_BOMB_MAP.put("VIP-W", "99999");
        VEHICLE_BOMB_MAP.put("VIP-J", "00000");
 
        VEHICLE_STRAIGHT_ASC_MAP.put("VIP-V", "01234");
        VEHICLE_STRAIGHT_ASC_MAP.put("VIP-K", "12345");
        VEHICLE_STRAIGHT_ASC_MAP.put("VIP-L", "23456");
        VEHICLE_STRAIGHT_ASC_MAP.put("VIP-M", "34567");
        VEHICLE_STRAIGHT_ASC_MAP.put("VIP-N", "45678");
        VEHICLE_STRAIGHT_ASC_MAP.put("VIP-X", "56789");
 
        VEHICLE_STRAIGHT_DESC_MAP.put("VIP-P", "98765");
        VEHICLE_STRAIGHT_DESC_MAP.put("VIP-Q", "87654");
        VEHICLE_STRAIGHT_DESC_MAP.put("VIP-R", "76543");
        VEHICLE_STRAIGHT_DESC_MAP.put("VIP-S", "65432");
        VEHICLE_STRAIGHT_DESC_MAP.put("VIP-T", "54321");
        VEHICLE_STRAIGHT_DESC_MAP.put("VIP-U", "43210");
 
        YU_AREA_MAP.put("郑州", "豫A·");
        YU_AREA_MAP.put("开封", "豫B·");
        YU_AREA_MAP.put("洛阳", "豫C·");
        YU_AREA_MAP.put("平顶山", "豫D·");
        YU_AREA_MAP.put("安阳", "豫E·");
        YU_AREA_MAP.put("鹤壁", "豫F·");
        YU_AREA_MAP.put("新乡", "豫G·");
        YU_AREA_MAP.put("焦作", "豫H·");
        YU_AREA_MAP.put("濮阳", "豫J·");
        YU_AREA_MAP.put("许昌", "豫K·");
        YU_AREA_MAP.put("漯河", "豫L·");
        YU_AREA_MAP.put("三门峡", "豫M·");
        YU_AREA_MAP.put("商丘", "豫N·");
        YU_AREA_MAP.put("周口", "豫P·");
        YU_AREA_MAP.put("驻马店", "豫Q·");
        YU_AREA_MAP.put("南阳", "豫R·");
        YU_AREA_MAP.put("信阳", "豫S·");
        YU_AREA_MAP.put("济源", "豫U·");
 
        SU_AREA_MAP.put("南京", "苏A·");
        SU_AREA_MAP.put("无锡", "苏B·");
        SU_AREA_MAP.put("徐州", "苏C·");
        SU_AREA_MAP.put("常州", "苏D·");
        SU_AREA_MAP.put("苏州", "苏E·");
        SU_AREA_MAP.put("南通", "苏F·");
        SU_AREA_MAP.put("连云港", "苏G·");
        SU_AREA_MAP.put("淮安", "苏H·");
        SU_AREA_MAP.put("盐城", "苏J·");
        SU_AREA_MAP.put("扬州", "苏K·");
        SU_AREA_MAP.put("镇江", "苏L·");
        SU_AREA_MAP.put("泰州", "苏M·");
        SU_AREA_MAP.put("宿迁", "苏N·");
    }
}

接下来就是重头戏了,就是生成车牌的一些规则

车牌规则

1、随机生成五位数字车牌号
2、随机生成车牌数字+字母或者全数字
3、随机生成车牌数字+字母(两位字母紧靠,三位数字紧靠)
4、指定车牌号码(数字加字母)

       说白了就是想要什么样的车牌自己输,只要没人选,就是你的

5、购买VIP号码 炸弹号,顺子号

       意思就是你定义的特殊号码,用来赚money的

6、车牌规则(是否是AABAA,或者ABCAB)
 
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
 
/**
 * 生成燃油车车牌
 */
public class VehicleRuleUtil {
 
    /**
     * 随机生成五位数字车牌号
     *
     * @return
     */
    public static String exeVehicleNumber() {
        Random random = new Random();
        String tempV = "";
        do {
            int i = random.nextInt(VehicleConstants.STR_ZERO_NICE.length);
            //重置车牌
            if (tempV.length() == 5) {
                tempV = "";
            }
            tempV += VehicleConstants.STR_ZERO_NICE[i];
        } while (tempV.length() < 5 || checkVipVehicle(tempV));
        return tempV;
    }
 
    /**
     * 牌照后五位(随机生成车牌数字+字母或者全数字)
     *
     * @param num 需要生成多少个车牌
     * @return
     */
    public static Set<String> vehicleRandomFIVE(int num) {
        Set<String> vehicleSet = new HashSet<>();
        String tempVehicle;//车牌
        Random random = new Random();
        while (vehicleSet.size() < num) {
            do {
                //再次循环需要初始化车牌
                tempVehicle = "";
                //牌照后五位
                for (int j = 0; j < 5; j++) {
                    int i = random.nextInt(VehicleConstants.STR_AZ_NICE.length);
                    tempVehicle += VehicleConstants.STR_AZ_NICE[i];
                }
                //如果牌照后五位大于2个字母则从新随机组成后五位
            } while (checkVehicleLetter(tempVehicle));
 
            //排除特殊号码
            if (!checkVipVehicle(tempVehicle)) {
                vehicleSet.add(tempVehicle);
            }
        }
        return vehicleSet;
    }
 
    /**
     * 牌照后五位(随机)
     * 两位字母紧靠
     * 三位数字紧靠
     *
     * @param num 需要生成多少个车牌
     * @param b   true 字母在前,数字在后
     * @return
     */
    public static Set<String> vehicleRandom(int num, boolean b) {
        Set<String> vehicleSet = new HashSet<>();
        String tempVehicle;//车牌
        Random random = new Random();
        while (vehicleSet.size() < num) {
            //生成两位字母
            int i1 = 0, i2 = 0;
            while (i1 == i2) {
                i1 = random.nextInt(VehicleConstants.STR_AZ.length);
                i2 = random.nextInt(VehicleConstants.STR_AZ.length);
            }
            String strA = VehicleConstants.STR_AZ[i1];
            String strZ = VehicleConstants.STR_AZ[i2];
            String vehicleA_Z = strA + strZ;
 
            //生成三位数字
            int j1 = 0, j2 = 0, j3 = 0;
            while (j1 == j2 || j2 == j3) {
                j1 = random.nextInt(VehicleConstants.STR_ZERO_NICE.length);
                j2 = random.nextInt(VehicleConstants.STR_ZERO_NICE.length);
                j3 = random.nextInt(VehicleConstants.STR_ZERO_NICE.length);
            }
            String strZERO = VehicleConstants.STR_ZERO_NICE[j1];
            String strONE = VehicleConstants.STR_ZERO_NICE[j2];
            String strTWO = VehicleConstants.STR_ZERO_NICE[j3];
            String vehicle0_9 = strZERO + strONE + strTWO;
 
            tempVehicle = b ? vehicleA_Z + vehicle0_9 : vehicle0_9 + vehicleA_Z;
 
            //排除特殊号码
            if (!checkVipVehicle(tempVehicle)) {
                vehicleSet.add(tempVehicle);
            }
        }
        return vehicleSet;
    }
 
    /**
     * 指定车牌号码(数字加字母)
     * 指定车牌小于3位时候会校验特殊敏感车牌
     *
     * @param appMap key 位数  value   车牌号码值
     * @param boo    是否要带字母    true 带 false不带
     * @param bAZ    true带2个字母 false带一个字母
     * @return
     */
    public static String vehicleAppoint(Map<Integer, String> appMap, boolean boo, boolean bAZ) {
        if (null == appMap || appMap.isEmpty()) {
            System.out.println("*******指定车牌至少有一位数字或者字母******");
            return null;
        }
        //指定车牌所有值
        if (appMap.size() == 5) {
            return buildMap(appMap);
        }
        //指定车牌未超过三位数则校验是否包含特殊敏感车牌
        boolean bl = false;
        if (appMap.size() < 3) {
            bl = true;
        }
 
        String vehicleTemp = buildMap(appMap);
        //使用StringBuilder避免在字符串中创建新的对象
        StringBuilder stringBuilder = new StringBuilder(vehicleTemp);
        //字母个数
        int strI = strCount(stringBuilder.toString());
        //生成两个字母做记录
        int inAZ = 0;
        //处理需要生成几个字母
        if (strI == 2) {
            boo = false;
        } else if (strI == 1 && boo) {
            bAZ = false;
        }
        //初始化需要生成字母的个数记录
        if (boo && bAZ) {
            inAZ = 2;
        } else if (boo && !bAZ) {
            inAZ = 1;
        }
        do {
            //初始化车牌
            if (stringBuilder.indexOf(VehicleConstants.STR_SYS) < 0) {
                stringBuilder = new StringBuilder(vehicleTemp);
                if (boo && bAZ) {
                    inAZ = 2;
                } else if (boo && !bAZ) {
                    inAZ = 1;
                }
            }
            for (int i = 0; i < stringBuilder.length(); i++) {
                if (VehicleConstants.STR_SYS.equals(String.valueOf(stringBuilder.charAt(i)))) {
                    //生成一个字母
                    if (boo && !bAZ) {
                        String s = executeONE(false);
                        stringBuilder.setCharAt(i, s.charAt(0));
                        boo = false;
                        //生成两个字母
                    } else if (boo && bAZ && inAZ != 0) {
                        String s = executeONE(false);
                        stringBuilder.setCharAt(i, s.charAt(0));
                        inAZ--;
                        //全是数字
                    } else if (!boo || inAZ == 0) {
                        String s = executeONE(true);
                        stringBuilder.setCharAt(i, s.charAt(0));
                    }
                }
            }
        } while (otherCount(stringBuilder.toString()) > 0 || (bl && checkVipVehicle(stringBuilder.toString())) || checkVehicleLetter(stringBuilder.toString()));
 
        return stringBuilder.toString();
    }
 
 
    /**
     * VIP号码    炸弹号,顺子号
     * 这里加一个记录输入VIP次数的记录,例如输入了3次或者三次以上
     * 做锁定操作,或者提示你这样做很危险,或者加入黑名单等等等等
     *
     * @param vipKey
     * @return
     */
    public static String vehicleVIP(String vipKey) {
        String vehicleStr = VehicleConstants.VEHICLE_BOMB_MAP.get(vipKey);
        if (null == vehicleStr) {
            vehicleStr = VehicleConstants.VEHICLE_STRAIGHT_ASC_MAP.get(vipKey) == null ? VehicleConstants.VEHICLE_STRAIGHT_ASC_MAP.get(vipKey) : VehicleConstants.VEHICLE_STRAIGHT_DESC_MAP.get(vipKey);
        }
        if (null == vehicleStr) {
            System.out.println("你小子在这跟我玩呢!");
            System.out.println("没有这个VIP等级:" + vipKey);
            System.out.println("只有下面这些,看清楚了!");
            vehicleShowVIP();
        }
        return vehicleStr;
    }
 
    /**
     * 判断是否在VIP号码段
     *
     * @param tempVehicle
     */
    private static boolean checkVipVehicle(String tempVehicle) {
        boolean b = checkVehicleSensitive(tempVehicle);
        boolean b1 = VehicleConstants.VEHICLE_BOMB_MAP.values().contains(tempVehicle);
        boolean b2 = VehicleConstants.VEHICLE_STRAIGHT_ASC_MAP.values().contains(tempVehicle);
        boolean b3 = VehicleConstants.VEHICLE_STRAIGHT_DESC_MAP.values().contains(tempVehicle);
        boolean b4 = checkVehicleDIS(tempVehicle);
        return b || b1 || b2 || b3 || b4;
    }
 
    /**
     * 随机生成一位数字或者字母
     *
     * @param b true数字  false 字母
     * @return
     */
    public static String executeONE(boolean b) {
        Random random = new Random();
        String tempStr;
        if (b) {
            tempStr = VehicleConstants.STR_ZERO_NICE[random.nextInt(VehicleConstants.STR_ZERO_NICE.length)];
        } else {
            tempStr = VehicleConstants.STR_AZ[random.nextInt(VehicleConstants.STR_AZ.length)];
        }
        return tempStr;
    }
 
    /**
     * 展示VIP号码  炸弹号,顺子号
     * 如果被人选走就不做展示了,这里要坐下排除
     */
    public static void vehicleShowVIP() {
        System.out.println("===========炸弹号==========");
        VehicleConstants.VEHICLE_BOMB_MAP.forEach((k, v) -> System.out.println("VIP等级【" + k + "】*****VIP号码:" + v));
        System.out.println("===========顺子号码==========");
        VehicleConstants.VEHICLE_STRAIGHT_ASC_MAP.forEach((k, v) -> System.out.println("VIP等级【" + k + "】*****VIP号码:" + v));
        VehicleConstants.VEHICLE_STRAIGHT_DESC_MAP.forEach((k, v) -> System.out.println("VIP等级【" + k + "】*****VIP号码:" + v));
    }
 
    /**
     * 生成两位字母,字母是紧靠一起的(可指定)
     *
     * @param str1 字母1
     * @param str2 字母2
     * @return
     */
    public static String executeA_Z(String str1, String str2) {
        if (!StringUtils.isBlank(str1) && !StringUtils.isBlank(str2)) {
            if (str1.equals(str2)) {
                System.out.println("***********两个字母不允许相同************");
            }
            if (VehicleConstants.LIST_IO.contains(str1) || VehicleConstants.LIST_IO.contains(str2)) {
                System.out.println("***********指定的字母不允许是I或者O************");
            }
            if (strCount(str1) == 0) {
                System.out.println("***********指定车牌第一个必须为字母***********");
            }
            if (strCount(str2) == 0) {
                System.out.println("***********指定车牌第二个必须为字母***********");
            }
        }
        Random random = new Random();
        //生成两位字母
        int i1, i2;
        do {
            i1 = random.nextInt(VehicleConstants.STR_AZ.length);
            i2 = random.nextInt(VehicleConstants.STR_AZ.length);
        } while (i1 == i2);
        if (!StringUtils.isBlank(str1) && StringUtils.isBlank(str2)) {
            //判断是否为字母
            if (strCount(str1) == 0) {
                System.out.println("***********指定车牌1必须为字母***********");
            }
            str2 = VehicleConstants.STR_AZ[i2];
            while (checkDubboA_Z(str1 + str2)) {
                int i = random.nextInt(VehicleConstants.STR_AZ.length);
                str2 = VehicleConstants.STR_AZ[i];
            }
            return str1 + str2;
        } else if (!StringUtils.isBlank(str2) && StringUtils.isBlank(str1)) {
            //判断是否为字母
            if (strCount(str2) == 0) {
                System.out.println("***********指定车牌2必须为字母***********");
            }
            str1 = VehicleConstants.STR_AZ[i2];
            while (checkDubboA_Z(str1 + str2)) {
                int i = random.nextInt(VehicleConstants.STR_AZ.length);
                str1 = VehicleConstants.STR_AZ[i];
            }
            return str1 + str2;
        } else if (StringUtils.isBlank(str1) && StringUtils.isBlank(str2)) {
            str1 = VehicleConstants.STR_AZ[i1];
            str2 = VehicleConstants.STR_AZ[i2];
        }
        return str1 + str2;
    }
 
    /**
     * 生成三位数字,数字是紧靠一起的(可指定)
     *
     * @param str1 数字1
     * @param str2 数字2
     * @param str3 数字3
     * @return
     */
    public static String execute0_9(String str1, String str2, String str3) {
        Random random = new Random();
        int j1, j2, j3;
        j1 = random.nextInt(VehicleConstants.STR_ZERO_NICE.length);
        j2 = random.nextInt(VehicleConstants.STR_ZERO_NICE.length);
        j3 = random.nextInt(VehicleConstants.STR_ZERO_NICE.length);
        if (StringUtils.isBlank(str1)) {
            str1 = VehicleConstants.STR_ZERO_NICE[j1];
        } else {
            if (numberCount(str1) == 0) {
                System.out.println("指定车牌1必须为数字");
            }
        }
        if (StringUtils.isBlank(str2)) {
            str2 = VehicleConstants.STR_ZERO_NICE[j2];
        } else {
            if (numberCount(str2) == 0) {
                System.out.println("指定车牌2必须为数字");
            }
        }
        if (StringUtils.isBlank(str3)) {
            str3 = VehicleConstants.STR_ZERO_NICE[j3];
        } else {
            if (numberCount(str3) == 0) {
                System.out.println("指定车牌3必须为数字");
            }
        }
        return str1 + str2 + str3;
    }
 
    /**
     * 判断车牌中的字母是否大于2或者字母是否相同
     *
     * @param tempVehicle
     * @return
     */
    public static boolean checkVehicleLetter(String tempVehicle) {
        int i = strCount(tempVehicle);
        boolean b = checkDubboA_Z(tempVehicle);
        return i > 2 || b;
    }
 
    /**
     * 判断有多少个数字
     *
     * @param str
     * @return
     */
    public static int numberCount(String str) {
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) >= '0' && str.charAt(i) <= '9') {
                num++;
            }
        }
        return num;
    }
 
    /**
     * 判断有多少字母
     *
     * @param str
     * @return
     */
    public static int strCount(String str) {
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            if ((str.charAt(i) >= 'A' && str.charAt(i) <= 'Z') || (str.charAt(i) >= 'a' && str.charAt(i) <= 'z')) {
                num++;
            }
        }
        return num;
    }
 
    /**
     * 判断车牌中的两个字母是否相同
     * 只用于燃油车车牌
     *
     * @param str
     * @return
     */
    public static boolean checkDubboA_Z(String str) {
        boolean b = false;
        String tempA = null, tempB = null;
        for (int i = 0; i < str.length(); i++) {
            if ((str.charAt(i) >= 'A' && str.charAt(i) <= 'Z') || (str.charAt(i) >= 'a' && str.charAt(i) <= 'z')) {
                if (null == tempA) {
                    tempA = String.valueOf(str.charAt(i));
                } else {
                    tempB = String.valueOf(str.charAt(i));
                }
            }
        }
        if (null != tempA && null != tempB) {
            b = tempA.equals(tempB);
        }
        return b;
    }
 
    /**
     * 判断是字母或者是数字
     * 两者都不是则为false
     *
     * @param str
     * @return
     */
    public static boolean checkStr(String str) {
        //特殊符号
        if (VehicleConstants.STR_SYS.equals(str)) {
            return true;
        }
        int i = numberCount(str);
        int i1 = strCount(str);
        return i == 1 || i1 == 1;
    }
 
    /**
     * 排序指定车牌
     *
     * @param appMap
     * @return
     */
    public static String buildMap(Map<Integer, String> appMap) {
        String s1 = appMap.get(1) == null ? "*" : appMap.get(1);
        String s2 = appMap.get(2) == null ? "*" : appMap.get(2);
        String s3 = appMap.get(3) == null ? "*" : appMap.get(3);
        String s4 = appMap.get(4) == null ? "*" : appMap.get(4);
        String s5 = appMap.get(5) == null ? "*" : appMap.get(5);
        boolean b = checkStr(s1) && checkStr(s2) && checkStr(s3) && checkStr(s4) && checkStr(s5);
        String tempS = s1 + s2 + s3 + s4 + s5;
        if (!b) {
            System.out.println("*******请填写正取的车牌数字或者字母*****" + tempS);
        }
        if (tempS.contains(VehicleConstants.STR_I) || tempS.contains(VehicleConstants.STR_O)) {
            System.out.println("***********指定的字母不允许是I或者O************" + tempS);
        }
        boolean bl = checkVehicleLetter(tempS);
        if (bl) {
            System.out.println("*******指定车牌大于2个字母,或者字母相同******" + tempS);
        }
        return bl ? null : tempS;
    }
 
    /**
     * 是否包含敏感车牌
     *
     * @param tempVehicle
     * @return
     */
    public static boolean checkVehicleSensitive(String tempVehicle) {
        for (String str : VehicleConstants.VEHICLE_SENSITIVE_LIST) {
            int i = tempVehicle.indexOf(str);
            if (i >= 0) {
                System.out.println("车牌【" + tempVehicle + "】随机生成的不允许有特殊敏感车牌号码" + str);
                return true;
            }
        }
        return false;
    }
 
    /**
     * 判断车牌(特殊车牌)
     * 是否是AABAA
     * 或者ABCAB
     *
     * @return
     */
    public static boolean checkVehicleDIS(String tempVehicle) {
        String begin = tempVehicle.substring(0, 2);
        String end = tempVehicle.substring(3);
        return begin.equals(end);
    }
 
    /**
     * 判断包含出数字和字母外的特殊字符数量
     *
     * @param str
     * @return
     */
    public static int otherCount(String str) {
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) >= '0' && str.charAt(i) <= '9') {
                continue;
            } else if (str.charAt(i) >= 'a' && str.charAt(i) <= 'z') {
                continue;
            } else if (str.charAt(i) >= 'A' && str.charAt(i) <= 'Z') {
                continue;
            } else {
                num++;
            }
        }
        return num;
    }
 
}

验证生成车牌号

 
 
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
 
public class VehicleNoTest {
    public static void main(String[] args) {
        String area = VehicleConstants.SU_AREA_MAP.get("苏州");
        //展示所有VIP车牌号码
        System.out.println("展示所有VIP车牌号码=============");
        VehicleRuleUtil.vehicleShowVIP();
 
        //随机生成车牌号码
        System.out.println("随机生成5个车牌号码============");
        Set<String> vehicleSet = VehicleRuleUtil.vehicleRandomFIVE(5);
//        vehicleSet.forEach(System.out::println);
        vehicleSet.forEach(v -> {
            System.out.print(area);
            System.out.println(v);
        });
 
        System.out.println("随机生成5个车牌号码,字母在前============");
        Set<String> strings = VehicleRuleUtil.vehicleRandom(5, true);
        strings.forEach(v -> {
            System.out.print(area);
            System.out.println(v);
        });
 
        System.out.println("随机生成5个车牌号码,数字在前============");
        Set<String> strings1 = VehicleRuleUtil.vehicleRandom(5, false);
        strings1.forEach(v -> {
            System.out.print(area);
            System.out.println(v);
        });
 
        //选择VIP号码
        String s = VehicleRuleUtil.vehicleVIP("VIP-J");
        System.out.println("指定的VIP车牌号码是:" + area + s);
 
        //生成两位字母
        System.out.println("生成两位字母,都可以指定");
        String a = VehicleRuleUtil.executeA_Z("A", "");
        System.out.println("生成的两位字母是==========" + a);
 
        //生成三位数字
        System.out.println("生成三位数字,都可以指定");
        String a1 = VehicleRuleUtil.execute0_9("0", "5", "");
        System.out.println("生成三位数字==========" + a1);
 
        for (int i = 0; i < 5; i++) {
            //指定数字字母
            Map<Integer, String> appMap = new HashMap<>();
            appMap.put(1, "5");
            appMap.put(2, "2");
            appMap.put(3, "1");
            String s1 = VehicleRuleUtil.vehicleAppoint(appMap, true, true);
            System.out.println("指定车牌号码(数字加字母)==========" + area + s1);
        }
        for (int i = 0; i < 5; i++) {
            //随机生成五位数字车牌号
            String s2 = VehicleRuleUtil.exeVehicleNumber();
            System.out.println("随机生成五位数字车牌号============" + area + s2);
        }
 
    }
}

执行结果

注:还有很多的细小规则,大家可以畅所欲言,留言必回

欢迎补充

/**

* 车牌号生成规则(车牌不允许重复)

* 1、指定第一位是数字

*  1》炸弹号   慎重,价值不可估量

*  2》第一位数字是5可以为正序或者倒序的顺子

*     后续数字如果小于5则只能正序

*     反之大于5只能倒序  才可以是顺子

*  3》只要第一位数字的,后面的随机

*  如果规则为空、默认随机

* 2、第一位为字母

*  1》后面随意

*  2》后面跟随意字母+三位数字

*  3》后面跟随意字母+指定三位数字

*  4》后面跟自定字母+三位数字

*  5》后面跟自定字母+指定三位数字

* 3、指定三位数

*  1》指定三位数字+随意字母

*      1》数字在前  字母在后

*      2》字母在前  数字在后

*  2》指定三位数字+指定字母

*      1》数字在前  字母在后

*      2》字母在前  数字在后

*  3》穿插字母之间

*  4》三位数字在第二三四位

* 4、指定两位字母

*  1》指定两位字母+随意三位数字

*      1》数字在前  字母在后

*      2》字母在前  数字在后

*  2》指定两位字母+指定三位数字

*      1》数字在前  字母在后

*      2》字母在前  数字在后

*  3》穿插数字之间

*  4》两位字母在第二位

*  5》两位字母在第三第四位

* 默认都是随机

*/

 


相关文章
|
Java
java使用正则表达式判断手机号,固定电话,身份证,邮箱,url,车牌号,日期,ip地址,mac,人名等
版权声明:本文为博主原创文章,如需转载,请标明出处。 https://blog.csdn.net/alan_liuyue/article/details/78983474 简介   1.
4251 0
|
2天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
4天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
4天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
4天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
20 3
|
4天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
53 2
|
12天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
43 6
|
27天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
25天前
|
存储 监控 小程序
Java中的线程池优化实践####
本文深入探讨了Java中线程池的工作原理,分析了常见的线程池类型及其适用场景,并通过实际案例展示了如何根据应用需求进行线程池的优化配置。文章首先介绍了线程池的基本概念和核心参数,随后详细阐述了几种常见的线程池实现(如FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)的特点及使用场景。接着,通过一个电商系统订单处理的实际案例,分析了线程池参数设置不当导致的性能问题,并提出了相应的优化策略。最终,总结了线程池优化的最佳实践,旨在帮助开发者更好地利用Java线程池提升应用性能和稳定性。 ####
|
27天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####