以Scala风格在Java中生成随机整数列表,Java8+是否有Scala的Seq.fill(n)(Random.nextInt)等效写法?
Seq.fill(n)(Random.nextInt)生成随机整数列表 嘿,这个问题问得很到位!Scala里Seq.fill(n)(Random.nextInt)那种简洁的写法确实让人印象深刻,不过在Java 8及更高版本中,我们完全可以借助Stream API实现几乎等效的功能,甚至还能根据需求做更多灵活调整。下面就给你几种实用的实现方式:
1. 最直接高效的实现:用Random.ints()生成流
这是最接近Scala原写法的方案,而且效率拉满——因为Random.ints()本身就是专门为生成随机整数流设计的:
import java.util.List; import java.util.Random; import java.util.stream.Collectors; public class RandomIntGenerator { public static void main(String[] args) { int count = 10; // 要生成的随机整数数量 Random random = new Random(); // 生成count个范围在Integer.MIN_VALUE到Integer.MAX_VALUE的随机整数 List<Integer> randomInts = random.ints(count) .boxed() // 将基本类型int包装为Integer .collect(Collectors.toList()); System.out.println(randomInts); } }
这段代码的效果和Scala的Seq.fill(n)(Random.nextInt)完全一致:生成指定数量的无范围限制的随机整数,最后收集为列表。
2. 生成指定范围的随机整数
如果需要像Scala的Random.nextInt(upperBound)那样生成有范围的随机数,只需要给ints()方法传入范围参数即可:
int count = 10; int upperBound = 100; // 生成0到99(左闭右开区间)的随机整数 Random random = new Random(); List<Integer> boundedRandomInts = random.ints(count, 0, upperBound) .boxed() .collect(Collectors.toList());
这里ints(long streamSize, int origin, int bound)的参数分别是:流的大小、随机数的起始值(包含)、上限值(不包含),灵活性拉满。
3. 更贴合Seq.fill函数风格的写法
如果你想更贴近ScalaSeq.fill那种“指定数量+生成函数”的写法,可以用Stream.generate():
int count = 10; Random random = new Random(); List<Integer> randomIntsViaGenerate = Stream.generate(random::nextInt) .limit(count) // 必须加!否则会生成无限流 .collect(Collectors.toList());
Stream.generate()接受一个Supplier(这里用方法引用random::nextInt提供生成逻辑),生成的是无限流,所以必须用limit(count)限制数量。这种写法更贴合Scala的函数式风格,但效率略低于Random.ints(),适合追求代码风格一致性的场景。
小补充:Java 16+的简化写法
如果你用的是Java 16及以上版本,可以用新增的Stream.toList()直接生成不可变列表,写法更简洁:
// Java 16+ 专属 List<Integer> immutableRandomInts = random.ints(count) .boxed() .toList();
内容的提问来源于stack exchange,提问作者Daniel

