创建自定义交替数字流

Zom*_*ies 11 java java-8 java-stream

如何IntStream在给定的顺序范围的中间开始,然后从中间开始流式传输下一个数字,并交替向左和向右.例如,对于数字的顺序给出的范围1 2 3 4 5,自定义序列会3 2 4 1 53 4 2 5 1取决于是否先从左边或右边第一.

我基本上试图从中间开始迭代一个数组并向外均匀地向外(不要先完​​全向左或向右).

我曾经尝试这样做只使用for循环但代码是凌乱的,我认为这将是好,只是排队的不是检查它的飞行(因为所有指数指出,有界异常的数字集合或流待检查).这是原始代码,我认为作为预先计算的int流更好:

        int middle = myArray.length / 2;
        Object value = myArray[middle]; //have to reference middle since the for loop won't
        //do operation on value
        for (int offset = 1; true; offset++) {
            int nextRight = middle + offset;
            int nextLeft = middle - offset;
            if (nextRight < myArray.length) { // Have to guard against exception, but can't catch exception ahead of time because left or null may not be empty.
                Object value = myArray[nextRight];
                //do operation on value
            }
            if (nextLeft >= 0) {
                Object value = myArray[nextRight];
                //do operation on value
            }
            if (nextRight >= myArray.length) {
                break; //exit logic
            }
            if (nextLeft < 0) {
                break; //exit logic
            }
        }
Run Code Online (Sandbox Code Playgroud)

Stu*_*rks 8

试试这个:

import static java.lang.Integer.signum;

static IntStream altSeq(int n) {
    return IntStream.iterate(2 * (n % 2) - 1, i -> -i - signum(i))
                    .map(i -> i / 2 + (n + 1) / 2)
                    .limit(n);
}
Run Code Online (Sandbox Code Playgroud)

例如,altSeq(5)产生:

[3, 2, 4, 1, 5]
Run Code Online (Sandbox Code Playgroud)

并且运行altSeq(6)产生:

[3, 4, 2, 5, 1, 6]
Run Code Online (Sandbox Code Playgroud)

简而言之,我们生成一个交替符号的升序序列:

1, -2, 3, -4, 5, ...
Run Code Online (Sandbox Code Playgroud)

这就是i -> -i - signum(i)表达式的作用.然后,我们除以2以便从中点获得偏移量:

0, -1, 1, -2, 2, ...
Run Code Online (Sandbox Code Playgroud)

这就是表达i / 2第一个词map来自的地方.然后我们添加范围1..n的中点(n + 1) / 2,即map表达式的第二项.对于n = 5,这给了我们

3, 2, 4, 1, 5, ...
Run Code Online (Sandbox Code Playgroud)

从1开始用于奇数长度序列.对于偶数长度,我们希望从-1开始.种子表达式2 * (n % 2) - 1计算偶数和奇数长度序列的正确种子值.

最后,我们申请limit(n)终止序列.


小智 2

该解决方案使用迭代器和流:

boolean toLeft = false;
int size = 5;

int half = size % 2 == 0 ? size / 2 : size / 2 + 1;
IntStream inferiorStream = IntStream.iterate (half, x -> x - 1);
IntStream superiorStream = IntStream.iterate (half, x -> x + 1);

OfInt a = toLeft 
          ? inferiorStream.iterator () 
          : superiorStream.iterator ();
OfInt b = toLeft 
          ? superiorStream.skip (1).iterator () 
          : inferiorStream.skip (1).iterator ();

IntStream stream = Stream.generate (() -> IntStream.concat (
    a.hasNext () ? IntStream.of (a.nextInt ()) : IntStream.empty (),
    b.hasNext () ? IntStream.of (b.nextInt ()) : IntStream.empty ()))
    .flatMapToInt (Function.identity ())
    .limit (size);

stream.forEach (System.out :: println);
Run Code Online (Sandbox Code Playgroud)

输出(toLeft = true):

3
4
2
5
1
Run Code Online (Sandbox Code Playgroud)

输出(toLeft = false):

3
2
4
1
5
Run Code Online (Sandbox Code Playgroud)