a-z、A-Z、0-9 共 62 個字符 → ArrayList<Character> 支持隨機索引。HashSet<Character> 存放字符,size() < 10 循環隨機取字符池元素 add() 自動去重。HashSet<String> 存放生成的字符串,size() < 10 循環調用單字符串生成方法。new ArrayList<>(hashSet) 保證順序性 (HashSet 無序)。public static ArrayList<Character> buildCharPool() {
ArrayList<Character> pool = new ArrayList<>();
for (char c = 'a'; c <= 'z'; c++) pool.add(c);
for (char c = 'A'; c <= 'Z'; c++) pool.add(c);
for (char c = '0'; c <= '9'; c++) pool.add(c);
return pool;
}
public static String genUniqueStr(ArrayList<Character> pool, int len) {
Set<Character> set = new HashSet<>();
while (set.size() < len) {
set.add(pool.get((int) (Math.random() * pool.size())));
}
StringBuilder sb = new StringBuilder();
set.forEach(sb::append);
return sb.toString();
}
public static List<String> genUniqueStrs(int count, int len) {
ArrayList<Character> pool = buildCharPool();
Set<String> set = new HashSet<>();
while (set.size() < count) set.add(genUniqueStr(pool, len));
return new ArrayList<>(set);
}
| 方案 | 核心 API | 優點 | 缺點 |
|---|---|---|---|
| HashSet + 隨機數 | HashSet<Character>、Math.random() | 代碼簡單、自動去重 | 隨機碰撞概率隨長度增大而上升 |
| StringBuilder + contains | StringBuilder、contains() | 可控生成順序、無碰撞 | contains() O(n),總體 O(n²) |
public static String genDigitStrSB(int len) {
StringBuilder sb = new StringBuilder();
while (sb.length() < len) {
int digit = (int) (Math.random() * 10);
if (!sb.toString().contains(String.valueOf(digit))) {
sb.append(digit);
}
}
return sb.toString();
}
public static void main(String[] args) {
String[] goods = {"可樂", "啤酒", "烤鴨", "蒼老師"};
List<String> codes = genUniqueStrs(4, 8); // 復用題二邏輯
Map<String, String> map = new LinkedHashMap<>(); // 保持插入順序
for (int i = 0; i < goods.length; i++) {
map.put(codes.get(i), goods[i]);
}
map.forEach((k, v) -> System.out.println(k + " : " + v));
}
HashSet;保序去重 → LinkedHashSet;排序去重 → TreeSet;鍵值綁定 → HashMap;保序鍵值 → LinkedHashMap;排序鍵值 → TreeMap。Math.random() 返回 [0,1),乘以上限再強轉 int;字符池用 List 支持 get(index) 隨機訪問。StringBuilder,避免 String += 產生大量中間對象。ArrayList<Character> 而非原始類型,編譯期類型安全。多線程環境下替換為:
Collections.synchronizedSet(new HashSet<>()) 或 ConcurrentHashMap.newKeySet() (Java 8+)。ThreadLocalRandom.current().nextInt(bound) 替代 Math.random() (性能更高、無競爭)。