《Java 普通编号生成工具类:OrdinaryCodeUtils 解析》
一、引言
在实际的项目开发中,我们经常需要生成各种类型的编号,如订单号、退货单号、退款单号等。这些编号通常需要具备唯一性和一定的规则性,以方便系统的管理和识别。本文将详细解析一个 Java 工具类 OrdinaryCodeUtils
,该工具类可以帮助我们生成不同类型的编号。
二、工具类概述
OrdinaryCodeUtils
是一个普通编号生成工具类。它提供了生成订单单号、退货单号、退款单号以及自定义编号的功能。以下是该工具类的主要特点:
- 可配置性:可以自定义加权因子、最大长度和日期格式。
- 唯一性:通过用户 ID 和时间戳确保生成的编号具有唯一性。
- 扩展性:支持生成自定义编码,用户可以指定编码前缀。
三、代码结构分析
1. 常量定义
/**
* 默认订单号编码类型
*/
private static final String DEFAULT_REGULAR_ORDER_CODE_TYPE = "PAO";
/**
* 默认退货单号编码类型
*/
private static final String DEFAULT_REGULAR_RETURN_ORDER_CODE_TYPE = "RAO";
/**
* 默认退款单号编码类型
*/
private static final String DEFAULT_REGULAR_REFUND_ORDER_CODE_TYPE = "RRO";
/**
* 默认加权因子
*/
private static final int[] DEFAULT_R = new int[]{7, 9, 6, 2, 8, 1, 3, 0, 5, 4};
/**
* 默认最大长度
*/
private static final int DEFAULT_MAX_LENGTH = 8;
/**
* 默认日期格式
*/
private static final String DEFAULT_DATE_FORMAT = "yyyyMMddHHmmssSSS";
这些常量分别定义了默认的订单号编码类型、退货单号编码类型、退款单号编码类型、加权因子、最大长度和日期格式。
2. 成员变量
/**
* 加权因子
*/
private int[] r;
/**
* 最大长度
*/
private int maxLength;
/**
* 日期格式
*/
private String dateFormat;
这些成员变量用于存储加权因子、最大长度和日期格式,用户可以通过构造函数进行自定义。
3. 构造函数
public OrdinaryCodeUtils() {
this(DEFAULT_R, DEFAULT_MAX_LENGTH, DEFAULT_DATE_FORMAT);
}
public OrdinaryCodeUtils(int[] r, int maxLength, String dateFormat) {
this.r = r;
this.maxLength = maxLength;
this.dateFormat = dateFormat;
}
提供了两个构造函数,一个是默认构造函数,使用默认的参数;另一个是自定义构造函数,允许用户传入自定义的加权因子、最大长度和日期格式。
4. 核心方法
toCode(Long userId)
/**
* 根据id进行加密+加随机数组成固定长度编码
*/
private String toCode(Long userId) {
String idStr = userId.toString();
StringBuilder sass = new StringBuilder();
for (int i = idStr.length() - 1; i >= 0; i--) {
sass.append(r[idStr.charAt(i) - '0']);
}
return sass.append(getRandom(maxLength - idStr.length())).toString();
}
该方法根据用户 ID 进行加密,并添加随机数,生成固定长度的编码。
generateRandomUserId()
private long generateRandomUserId() {
Random random = new Random();
return System.currentTimeMillis() + random.nextLong() % 1000000;
}
生成随机的用户 ID,确保生成的编号具有唯一性。
getDateTime()
private String getDateTime() {
DateFormat sdf = new SimpleDateFormat(dateFormat);
return sdf.format(new Date());
}
生成当前时间的时间戳,格式由 dateFormat
决定。
getRandom(long n)
private long getRandom(long n) {
long min = 1;
long max = 9;
for (int i = 1; i < n; i++) {
min *= 10;
max *= 10;
}
return (((long) (new Random().nextDouble() * (max - min)))) + min;
}
生成指定长度的随机数。
getCode(Long userId)
private synchronized String getCode(Long userId) {
if (userId == null) {
userId = generateRandomUserId();
}
return getDateTime() + toCode(userId);
}
生成不带类别标头的编码,如果用户 ID 为空,则生成随机的用户 ID。
5. 对外提供的方法
obtainOrderCode(Long userId)
public String obtainOrderCode(Long userId) {
return DEFAULT_REGULAR_ORDER_CODE_TYPE + getCode(userId);
}
生成订单单号编码,在不带类别标头的编码前加上默认的订单号编码类型。
obtainReturnCode(Long userId)
public String obtainReturnCode(Long userId) {
return DEFAULT_REGULAR_RETURN_ORDER_CODE_TYPE + getCode(userId);
}
生成退货单号编码,在不带类别标头的编码前加上默认的退货单号编码类型。
obtainRefundCode(Long userId)
public String obtainRefundCode(Long userId) {
return DEFAULT_REGULAR_REFUND_ORDER_CODE_TYPE + getCode(userId);
}
生成退款单号编码,在不带类别标头的编码前加上默认的退款单号编码类型。
obtainCustomizeCode(String prefix, Long userId)
public String obtainCustomizeCode(String prefix, Long userId) {
return prefix + getCode(userId);
}
生成自定义编码,用户可以指定编码前缀。
四、使用示例
public class Main {
public static void main(String[] args) {
OrdinaryCodeUtils utils = new OrdinaryCodeUtils();
Long userId = 12345L;
// 生成订单单号编码
String orderCode = utils.obtainOrderCode(userId);
System.out.println("订单单号编码: " + orderCode);
// 生成退货单号编码
String returnCode = utils.obtainReturnCode(userId);
System.out.println("退货单号编码: " + returnCode);
// 生成退款单号编码
String refundCode = utils.obtainRefundCode(userId);
System.out.println("退款单号编码: " + refundCode);
// 生成自定义编码
String customizeCode = utils.obtainCustomizeCode("CUST", userId);
System.out.println("自定义编码: " + customizeCode);
}
}
在上述示例中,我们创建了 OrdinaryCodeUtils
对象,并调用其不同的方法生成了订单单号编码、退货单号编码、退款单号编码和自定义编码。
执行结果如下:
五、总结
OrdinaryCodeUtils
工具类为我们提供了一种简单、灵活的方式来生成不同类型的编号。通过自定义加权因子、最大长度和日期格式,我们可以根据实际需求生成符合规则的编号。同时,该工具类通过用户 ID 和时间戳确保了生成的编号具有唯一性,适用于各种需要编号管理的系统。