可用Stream.generate(Math::random)创建无限随机数流并用limit()截取,适合压力测试数据生成;支持链式映射、范围转换、结构化对象构造及多线程安全使用。

可以用 Stream.generate(Math::random) 创建无限随机数流,再通过 limit() 截取所需数量,直接用于压力测试数据生成。
基础用法:生成固定数量的随机 double
这是最常用的方式,适合模拟请求参数、延迟时间、负载权重等场景:
-
Stream.generate(Math::random).limit(1000)生成 1000 个 [0.0, 1.0) 区间的随机 double - 可链式操作,比如
.mapToLong(x -> (long)(x * 1000))转为 0–999 的长整型 ID - 注意:
Math.random()是线程安全的,适合多线程压测环境
生成带范围/类型的随机数据
单纯 Math::random 输出是 double,需手动映射成业务需要的格式:
- 生成 1–100 的随机整数:
Stream.generate(() -> (int)(Math.random() * 100) + 1) - 生成指定长度的随机字符串(如订单号):
Stream.generate(() -> UUID.randomUUID().toString().substring(0, 8)) - 生成随机枚举值:
Stream.generate(() -> Status.values()[(int)(Math.random() * Status.values().length)])
结合 Supplier 构建结构化测试对象
压力测试常需完整 POJO(如用户请求体),可用 lambda 封装构造逻辑:
-
推荐写法:
Stream.generate(() -> new ApiRequest(UUID.randomUUID().toString(),(int)(Math.random() * 100),List.of("A", "B", "C").get((int)(Math.random() * 3)))) - 避免在 generate 中做重操作(如 DB 查询、文件读取),否则拖慢流生成速度,影响压测真实性
- 若需复用同一组数据多次,记得用
.toList()或.toArray()缓存,别反复调用无限流
实际压测中注意事项
生成流只是第一步,真实压测需配合执行策略:
- 用
parallel()并行处理时,Math.random()性能足够,但注意后续操作是否线程安全(如共享计数器需用AtomicInteger) - 避免直接打印整个流(如
forEach(System.out::println)),海量数据会卡死终端;改用forEachOrdered+ 采样日志 - 与 JMH 或 Gatling 集成时,把流作为数据源供给,而非在每次请求中重新生成——提升复用性、减少 GC 压力


















