java - IntStream 的随机排列
问题描述
时不时地我发现自己有索引循环,我想将顺序排列为一些随机顺序。我通常从类似的东西过渡
for (int i = 0; i < max; i++) {
// do stuff with i
}
至
List<Integer> indices = IntStream.range(0, max)
.boxed()
toCollection(() -> new ArrayList(max)));
Collections.shuffle(indices);
for (int i = 0; i < max; i++) {
int index = indices.get(i);
// do stuff with index
}
这既不高效也不优雅。是否可以在某个范围内创建一个Stream
(理想情况下是一个),但它是否返回其元素被打乱?IntStream
我正在考虑以下内容:
IntStream.range(0, max)
.shuffled() // this method doesn't exist
.forEach(IntConsumer::accept);
结果IntStream
仍应仅包含该范围内的所有[0, max)
元素一次。
这不是这个问题的重复,因为我不想创建一个List
并随机播放它。该解决方案具有巨大的开销,因为它与Integer
s 一起工作,同时还冗余地创建和改组 a List
。我在自己的示例中提供了该解决方案,因此我完全了解这种方法。
解决方案
这个怎么样?它与您拥有的几乎相同,只是它封装了所有细节,并为您提供了一个纯粹的IntStream
. 它也不必做太多的装箱和拆箱。
public class ShuffledIntStream {
public static IntStream to(int max) {
Random r = new Random();
int[] values = new int[max];
for (int i = 0; i < max; i++) {
values[i] = i;
}
for (int i = max; i > 1; i--) {
swap(values, i - 1, r.nextInt(max));
}
return IntStream.of(values);
}
private static void swap(int[] values, int i, int j) {
int temp = values[i];
values[i] = values[j];
values[j] = temp;
}
}
推荐阅读
- spring - Keycloak - 找不到指定孩子的公钥
- java - 断言对象是一个有效的顶级 json 可序列化
- google-cloud-platform - 当我使用 Google Cloud Application Flex 提供的 Memcache 服务时,“session_memcached_host:”会是什么。引擎?
- angular - 具有延迟加载和子路由设置的 Angular
- javascript - matter.js 物理引擎中的结果总是不同的
- android - java.lang.NullPointerException:空对象引用上的 FloatingActionButton.setVisibility(int)'
- django - Django selenium:i18n 部分有效
- r - NA 使用 pivot_wider
- python - 从数据集中生成 Wordcloud,仅使用一列
- python - 具有条件增量的 Python-For 循环的行为(给出错误的输出)