如何使用Stream API随机播放流? [英] How to shuffle a stream using the Stream API?
问题描述
我决定采用功能性方法来生成字符串或随机字符,到目前为止,我想到了这一点,它的性能要比装箱更好,然后使用StringJoiner
作为收集器:
I decided to take the functional approach in generating a string or random characters, so far I came up with this, it should perform better than boxing and then using a StringJoiner
as collector:
Random random = new Random();
String randomString = IntStream.concat(
random.ints(8, 'a', 'z'),
random.ints(8, 'A', 'Z')
)
.collect(
StringBuilder::new,
(sb, i) -> sb.append((char)i),
(sb1, sb2) -> sb1.append(sb2)
).toString();
我想生成一个16个字符的流,范围从a-z或A-Z,我遇到的问题是我不知道如何对这两个流进行混洗.
I want to generate a stream of 16 characters, ranging from a-z or A-Z, the problem I have is that I do not know how to shuffle both streams.
我知道我在这里使用IntStream.concat
,它将简单地将两个流连接在一起,我正在寻找以下任意一个:
I know that I am using IntStream.concat
here, which will simply concatenate both streams, I'm looking for either of the following:
- 像
IntStream.concat
这样的静态运算符,在合并流时进行改组. - 像
sorted()
这样的流运算符.
- A static operator like
IntStream.concat
that does the shuffling when merging the streams. - A stream operator like
sorted()
.
在我看来,这两种方法都是可行的,但是,如何使运算符与sorted()
相似,我对此特别感兴趣.这里的关键点是它是一个有状态的运算符,因为它需要在操作之前先查看整个流,是否有办法在流序列中注入一个有状态的运算符?
Both ways are viable in my opinion, however I am especially intrigued by how to make an operator alike sorted()
. The key point here is that it is an operator that is stateful as it needs to see the whole stream before it can operate, is there a way to inject a stateful operator in a stream sequence?
到目前为止,除了将它们改组所需的工作之外,这些操作似乎并不适合Java 8中的功能方法.
So far the operations, excluding the needed work to shuffle them, seem to not be appropiate for a functional approach in Java 8.
推荐答案
您觉得太扭曲了
Random random = new Random();
String randomString=random.ints(16, 0, 26*2).map(i->(i>=26? 'a'-26: 'A')+i)
.collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
由于您已经具有随机值的来源,因此没有必要调用随机播放功能(这种功能在 streams 上效果不佳).
Since you already have a source of random values there is no point in calling for a shuffle function (which would not work very well with streams).
请注意,您还可以在String
中明确定义允许的字符,并使用以下命令选择它们:
random.ints(16, 0, allowed.length()).map(allowed::charAt)
Note that you also could define the allowed chars in a String
explicitly and select them using:
random.ints(16, 0, allowed.length()).map(allowed::charAt)
类似的模式适用于从随机访问List
中进行选择.
Similar pattern applies to selecting from a random access List
.
更新:如果您想让代码清楚地显示允许的字符的两个范围性质,则可以将Stream.concat
方法与上述的char
选择解决方案结合使用:
Update: If you want to have code clearly showing the two ranges nature of the allowed characters you can combine your Stream.concat
approach with the char
selection solution described above:
StringBuilder allowed=
IntStream.concat(IntStream.rangeClosed('a', 'z'), IntStream.rangeClosed('A', 'Z'))
.collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append);
String randomString=random.ints(16, 0, allowed.length()).map(allowed::charAt)
.collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
(注意:我用rangeClosed
替换了range
,我怀疑它符合您的原始意图,但它没有实现Random.ints(…, 'a', 'z')
的作用).
(Note: I replaced range
with rangeClosed
which I suspect to match your original intentions while it does not do what Random.ints(…, 'a', 'z')
would do).
这篇关于如何使用Stream API随机播放流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!