如何使用Stream API随机播放流? [英] How to shuffle a stream using the Stream API?

查看:141
本文介绍了如何使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆