Java,使用 Maps/Collections 生成唯一序列号

Java, Generating a unique serial number using Maps/Collections

我目前有一个 class 负责生成唯一的序列号,提供参数 'full name' 和 'Year'。

public static CustomerNumber getInstance(CustomerName name, Date dateIssued) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(dateIssued);
    int yearIssued = cal.get(Calendar.YEAR);

    return name.getFirstName().charAt(0) + name.getLastName().charAt(0) + "-" + yearIssued + "-" + serialNumber;
}

预期的结果类似于:

'John Smith', 2018 --> JS-2018-01,

'Joe Scott', 2018 --> JS-2018-02,

'Jaden Scott', 2018 --> JS-2018-03

'Maggie Scott', 2018 --> MS-2018-01,

基本上,如果前缀(首字母和年份)已经存在,则必须应用序列号增量来表示它是一个新人。

我尝试应用某种地图,但我是 java/ 编程的新手,希望得到一些建议

一种方法是使用 HashMap<String, Integer>。该地图将存储用作 serialNumber 的最后一个值。每次计算新客户的 ID 时,使用 merge 增加哈希映射的值。

private static Map<String, Integer> serialNumbersMap = new HashMap<>();

public static CustomerNumber getInstance(CustomerName name, LocalDate dateIssued) {
    // I recommend you use java.time.LocalDate here
    int yearIssued = dateIssued.getYear();

    String key = name.getFirstName().charAt(0) + name.getLastName().charAt(0) + "-" + yearIssued;

    int serialNumber = serialNumbersMap.merge(key, 1, Integer::sum);
    String id = key + (serialNumber < 10? "-0": "-") + serialNumber;
    return id;
}

如果可以使用相同的客户名称和日期多次调用 getInstance,并且如果发生这种情况您希望 return 相同的 ID,则需要另一个映射来存储已知的客户 ID。

private static Map<String, String> knownIDsMap = new HashMap<>();

如果您以前看过客户名称,请先在这张地图上打卡。如果没有,请执行上述操作,否则 return 地图中的值。

public static CustomerNumber getInstance(CustomerName name, LocalDate dateIssued) {
    int yearIssued = dateIssued.getYear();

    String knownIDKey = name.getFirstName() + name.getLastName() + yearIssued;

    String knownID = knownIDsMap.get(knownIDKey);

    if (knownID != null) {
        return knownID;
    }

    // same as above...

    knownIdsMap.put(knownIDKey, id);
    return id;
}

为了更好的实现,创建一个 class CustomerIDInfo 封装 CustomerNameLocalDate,覆盖 equalshashcode。然后,您可以创建 HashMap<CustomerIDInfo, String> 类型的地图,而无需执行所有这些字符串操作。

那么,您只是想缓存生成的序列号并在重复时递增它,对吧?如果是这样,你只需要“设置”,你可以做 while 循环来递增它直到它是唯一的。

String baseValue = name.getFirstName().charAt(0) + name.getLastName().charAt(0) + "-" + yearIssued + "-";
String value = baseValue + serialNumber;
while(set.contains(value)){
    value = baseValue + (serialNumber++);
}
set.add(value);
return value;