1. 概述
在本教程中,我们将介绍如何在 Kotlin 中生成一个随机的字母数字字符串。我们将通过三种不同的方式来实现:
- 使用 Java 的
Random
类(通过ThreadLocalRandom
) - 使用 Kotlin 自带的
kotlin.random.Random
- 使用 Apache Commons Lang 提供的
RandomStringUtils
每种方法都会结合单元测试验证其正确性,并在最后对比其优劣。
2. 依赖配置
在开始之前,如果你打算使用 Apache Commons Lang 提供的工具类,需要在 pom.xml
中添加如下依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
此外,我们定义一个常量来表示生成字符串的长度:
const val STRING_LENGTH = 10
3. 单元测试设计
为了验证每种方法生成的字符串是否符合要求,我们编写一个通用的高阶函数 verifyTheSolution()
来统一验证:
private fun verifyTheSolution(randomFunc: () -> String) {
val randoms = List(10_000) { randomFunc() }
assertTrue { randoms.all { it.matches(Regex("^[0-9a-zA-Z]+$")) } } // 全部是字母数字
assertTrue { randoms.none { it.length != STRING_LENGTH } } // 长度固定
assertTrue { randoms.size == randoms.toSet().size } // 没有重复
}
这个函数会执行目标函数 10000 次,然后验证:
✅ 所有字符串都只包含字母和数字
✅ 每个字符串长度都为 10
✅ 没有任何重复字符串(虽然理论上可能有,但概率极低)
4. 使用 Java 的 Random
Java 提供了 ThreadLocalRandom
,每个线程有自己的 Random
实例,避免多线程竞争。我们可以通过它来生成随机索引,再从字符池中取出字符拼接字符串。
val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
fun randomStringByJavaRandom() = ThreadLocalRandom.current()
.ints(STRING_LENGTH.toLong(), 0, charPool.size)
.asSequence()
.map(charPool::get)
.joinToString("")
⚠️ 注意:ThreadLocalRandom
是从 JDK 7 开始支持的。如果使用 Random
类在多线程环境下可能会导致性能下降或冲突。
我们可以通过如下测试验证:
@Test
fun givenAStringLength_whenUsingJava_thenReturnAlphanumericString() {
verifyTheSolution { randomStringByJavaRandom() }
}
✅ 该方法测试通过。
5. 使用 Kotlin 的 Random
Kotlin 1.3 开始提供了跨平台的 kotlin.random.Random
类,它在 JVM 上底层使用的是 java.util.Random
(JDK 6/7) 或 ThreadLocalRandom
(JDK 8+)。
我们可以这样实现:
fun randomStringByKotlinRandom() = (1..STRING_LENGTH)
.map { Random.nextInt(0, charPool.size).let { charPool[it] } }
.joinToString("")
同样,我们也可以用更简洁的方式:
fun randomStringByKotlinCollectionRandom() = List(STRING_LENGTH) { charPool.random() }.joinToString("")
这种方式更易读,也更 Kotlin 风格。
测试代码如下:
@Test
fun givenAStringLength_whenUsingKotlinCollectionRandom_thenReturnAlphanumericString() {
verifyTheSolution { randomStringByKotlinCollectionRandom() }
}
✅ 两种写法都通过了测试。
6. 使用 Apache Commons Lang
Apache Commons Lang 提供了一个非常方便的工具类 RandomStringUtils
,可以一行代码搞定随机字符串生成:
fun randomStringByApacheCommons() = RandomStringUtils.randomAlphanumeric(STRING_LENGTH)
这方法内部使用的是 java.util.Random
,所以如果你需要生成安全的 token,比如用于密码重置、验证码等场景,建议使用 SecureRandom
或 Apache Commons Crypto 中的 CryptoRandom
。
测试代码如下:
@Test
fun givenAStringLength_whenUsingApacheCommons_thenReturnAlphanumericString() {
verifyTheSolution { randomStringByApacheCommons() }
}
✅ 测试通过。
7. 总结
我们通过三种方式实现了在 Kotlin 中生成随机字母数字字符串:
方法 | 是否线程安全 | 是否跨平台 | 是否安全 | 说明 |
---|---|---|---|---|
Java Random (ThreadLocalRandom ) |
✅ | ❌ | ❌ | 推荐用于一般场景,性能较好 |
Kotlin Random |
✅ | ✅ | ❌ | 语法更简洁,适合 Kotlin 项目 |
Apache Commons RandomStringUtils |
❌ | ❌ | ❌ | 快速实现,适合已有依赖的项目 |
📌 安全提示:如果你需要生成用于安全场景的随机字符串(如 token、验证码、密码),建议使用 SecureRandom
或 CryptoRandom
。
完整代码已上传至 GitHub:点击查看