0

I'm trying to do the following: if I have an array numbers which has the numbers

{1,4,9,16,25,36,49,64,81,100}

I want to calculate recursively the differences between two succeeding elements. So first between element 1 and 0, then 2 and1, etc.

Once I have those differences I want to calculate the differences between any two succeeding elements in that array.

So if you start with

{1,4,9,16,25,36,49,64,81,100}

you go to

{3,5,7,9,11,13,15,17,19}

and then to

{2,2,2,2,2,2,2,2}

I know how to program this, but only in Java 7 style and not in Java 8 Lambda expression style. This was my attempt:

    Integer[] numbers = new Integer[] {1,4,9,16,25,36,49,64,81,100};
    for (int i=0;i<3;i++)
    {
        int length = numbers.length;
        numbers = IntStream.range(1, length)
                .mapToObj(a->numbers[a]-numbers[a-1])
                .toArray(b->new Integer[length-1]);
    }

This doesn't work because Java requires the array numbers to be final when using lambda expressions, but then I cannot call the same code recursively on the same array. How can I solve this?

Héctor van den Boorn
  • 1,218
  • 13
  • 32
  • Take a look at https://stackoverflow.com/questions/20470010/collect-successive-pairs-from-a-stream –  Jun 17 '15 at 14:14

2 Answers2

0

How about make a UnaryOperator that does this for you, then you can pass in the array and use this to calculate the new array while maintaining that the variables used in the lambda are effectively final:

int numbers[] = new int[] {1, 4, 9, 16, 25, 36, 49, 64, 81, 100};
UnaryOperator<Integer[]> differenceFunc = ns -> IntStream.range(1, ns.length)
    .map(i -> ns[i] - ns[i - 1])
    .toArray();
for (int x = 0; x < 3; ++x) {
    numbers = difference.apply(numbers);
}
Oli
  • 919
  • 8
  • 16
-1

You can use Stream.iterate from which you apply the "decrement" function. You skip the first x elements to get the desired array (it may not be the optimal way to do it), or you can limit it to x invocations and collect the arrays into a list for example:

int[] numbers = {1,4,9,16,25,36,49,64,81,100};

Optional<int[]> opt =
    Stream.iterate(numbers, arr -> IntStream.range(1, arr.length)
                                            .map(i -> arr[i] - arr[i-1])
                                            .toArray())
          .skip(2)
          .findFirst();

opt.ifPresent(a -> System.out.println(Arrays.toString(a)));

For example:

skip 0 => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 
skip 1 => [3, 5, 7, 9, 11, 13, 15, 17, 19]
skip 2 => [2, 2, 2, 2, 2, 2, 2, 2]
skip 3 => [0, 0, 0, 0, 0, 0, 0]
Alexis C.
  • 91,686
  • 21
  • 171
  • 177