IntStream.iterate与要添加的交替值

我想创建一个整数序列,最好是一个IntStream遵循特定条件的 。一些简单的例子来解释我想要做什么:

从 0 开始的前 10 个偶数的序列(这里我没有问题,我用下面的代码片段来做)

IntStream.iterate(0, i -> i + 2).limit(10); 

//0,2,4,6,8,10,12,14,16,18

前 10 个数字从 0 开始的序列,交替添加 2 和 3 到原始数字;所需的输出:

 //0,2,5,7,10,12,15,17,20,22

我很愿意也使用了此方案 IntStream.iterate()还是IntStream.generate(),但不能让它在我自己的。我正在使用经典的 for 循环,它可以工作,但对于这样一个相对简单的任务来说有点长

List<Integer> list = new ArrayList<>();
list.add(0);
for(int i = 1, j = 1; i < 10; i++, j *= -1){
    if(j > 0){
        list.add(list.get(i-1) + 2);
    }
    else{
        list.add(list.get(i-1) + 3);
    }
}

//and then stream over the list to get IntStream
list.stream().mapToInt(Integer::intValue);

使用IntStream.iterate()或实现与上述相同的任何简单方法 IntStream.generate()

对于三个或更多交替值,我不知道如何优雅地做到这一点。例如,如果我想通过将 +2、+5 和 +7 交替添加到具有所需输出的前一个数字来创建从 0 开始的前 10 个数字的序列:

//0,2,7,14,16,21,28,30,35,42

我曾想过i%3在带有 3 个 if-else 块或 switch case 的 for 循环中使用,但是当我需要更多交替值并且我必须添加更多ifscases. 任何想法如何做到这一点?如果您认为IntStream.iterate()IntStream.generate()不是解决所描述任务的正确方法,我也愿意接受其他方法。

回答

以产生由交替加入2或3的流时,可以观察到,每一个其他值将是5的倍数。因此,如果先前的值是由5没有余整除,就要加2,否则,我们应该添加3。

IntStream.iterate(0, i -> (i % 5 == 0) ? (i + 2) : (i + 3)).limit(10)

对于两个交替的整数,会有这种方法不可行的情况。如果其中一个数字是另一个数字的因数,那将是不可能的。例如2和4。

对于此类情况,您可以使用更通用的方法并在迭代器之外维护一个布尔值。

它不遵循函数式风格,因为您的函数有副作用,但嘿,Java 不是函数式语言。它足够直观。

AtomicBoolean isTwo = new AtomicBoolean(true);
IntStream.iterate(0, i -> isTwo.getAndSet(!isTwo.get()) ? (i + 2) : (i + 4))

对于 3 个交替值,在一般情况下,您可以对布尔值执行类似的操作,但使用在 0、1 和 2 之间循环的整数计数器。

AtomicInteger counter = new AtomicInteger(0);
IntStream.iterate(0, i -> {
        int count = counter.getAndUpdate(cnt -> (cnt + 1) % 3);
        if (count == 0) return i + 2;
        if (count == 1) return i + 5;
        if (count == 2) return i + 7;
        // As long as modulus value == number of if-conditions, this isn't possible
        throw new RuntimeException("Only 3 possible values");
    })
    .limit(10)


以上是IntStream.iterate与要添加的交替值的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>