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、验证码、密码),建议使用 SecureRandomCryptoRandom

完整代码已上传至 GitHub:点击查看


原始标题:Generate a Random Alphanumeric String in Kotlin

» 下一篇: Scala 类型体系详解