如何以适当的顺序收集和合并Java流中的不同对象?

如何以适当的顺序收集和合并Java流中的不同对象?,java,java-stream,Java,Java Stream,我有两个目标: String y = "Y" String r = "R" 如何收集此值并将其与Java流合并以接收此行: “yyryyryy” 流可以是无止境的,但应以YY开始,以YY结束,但每三个值应为R有限序列 假设您想创建一个包含Y或R,随机的有限字符序列,只需创建一些next()方法并重复调用它: public final class SequenceGenerator { private final String[] elements; private final

我有两个目标:

String y = "Y"
String r = "R"
如何收集此值并将其与Java流合并以接收此行:
“yyryyryy”

流可以是无止境的,但应以
YY
开始,以
YY
结束,但每三个值应为
R

有限序列 假设您想创建一个包含
Y
R
随机的有限字符序列,只需创建一些
next()
方法并重复调用它:

public final class SequenceGenerator {
    private final String[] elements;
    private final Random rnd;

    public SequenceGenerator(Collection<String> elements) {
        this.elements = elements.toArray(new String[elements.size()]);
        rnd = new Random();
    }

    public String next() {
        return elements[rnd.nextInt(elements.length)];
    }

    public String generate(int amountOfElements) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < amountOfElements; i++) {
            sb.append(next());
        }
        return sb.toString();
    }
}
可以打印以下内容:

YYRYYRYYRYY

源源不断 您还可以在这里很好地使用
API创建一个无穷无尽的流:

SequenceGenerator gen = new SequenceGenerator(List.of("Y", "R"));
Stream<String> sequence = Stream.generate(gen::next);
实际上,我们还需要考虑另一个要求。结尾处的
YY
的串联必须对在每三个位置强制执行
R
的规则有效。因此,对于
generate
而言,
amountfements
必须比可除以
3
的值大两倍,否则结果值无效

我们需要考虑边缘情况,
amountfements
必须至少为
5
,每个较小的序列都无效
yyry
是第一个有效序列。修改后的方法:

public String generate(int amountOfElements) {
    if (amountOfElements < 5 || (amountOfElements - 2) % 3 != 0) {
        throw new IllegalArgumentException("Invalid sequence length");
    }
    // ...
}
生成公共字符串(int-amountfements){
如果(amountfelements<5 | |(amountfelements-2)%3!=0){
抛出新的IllegalArgumentException(“无效序列长度”);
}
// ...
}

如果您想使用流,您必须执行以下操作:

final long iterateLimit = 20;
final String sequence = "YYR";
final String suffix = "YY";
final String yyrString = Stream.generate(() -> sequence)
                               .limit(iterateLimit)
                               .collect(Collectors.joining())
                               .concat(suffix);

我提供了“YYR”的生成序列,并在创建字符串后添加后缀“YY

您的要求中存在矛盾“流可以是无止境的,但应该……以YY结尾”

从我所看到的,您只需要一个重复的
Y
Y
R
,其结构如下

String y = "Y";
String r = "R";
String[] toRepeat = { y, y, r };
Stream.generate(() -> toRepeat).flatMap(Arrays::stream)
所以你可以打印这个无休止的序列:

Stream.generate(() -> toRepeat).flatMap(Arrays::stream)
      .forEach(System.out::println);
Stream.iterate(y+y, s -> s+r+y+y)
    .skip(10)
    .findFirst()
    .ifPresent(System.out::println);
要将其转换为以“yy”结尾的有限序列,请使用一个比可被三整除的数字小一的限制,例如五、八、十一、332等

然后,您可以将流收集/合并为
字符串

String[] toRepeat = { y, y, r };
String seq = Stream.generate(() -> toRepeat).flatMap(Arrays::stream)
      .limit(11)
      .collect(Collectors.joining());
System.out.println(seq);
除了使用
.collect(Collectors.joining())
,您还可以使用
.reduce(“,String::concat)
,但前者通常更有效

另一种方法是迭代满足您需求的所有序列:

Stream.iterate(y+y, s -> s+r+y+y)
    .forEach(System.out::println);
这可用于查找第n个有效序列:

Stream.generate(() -> toRepeat).flatMap(Arrays::stream)
      .forEach(System.out::println);
Stream.iterate(y+y, s -> s+r+y+y)
    .skip(10)
    .findFirst()
    .ifPresent(System.out::println);

流对该任务没有帮助。忘了他们吧。将您想要的元素添加到StringBuilder中(或者在一个表达式中直接使用+运算符连接它们),看起来没有更好的解决方案了,就是使用旧样式生成并合并所有这些元素loop@Igor好吧,我给你看了溪流法。它只使用
next
方法,该方法非常轻量级,根本没有循环。删除
generate
方法并使用
Stream.generate(gen::next)
。那么你就有了源源不断的信息。为什么不
amountfelements%3!=2