Necesito generar una secuencia de enteros que cada valor se basa en el valor antes de acuerdo con alguna función matemática.

Por ejemplo, digamos que quiero tomar el último número y agregar 10: [1, 11, 21, 31, 41, ...]

Por supuesto, la función real es mucho más compleja.

Intenté tomar el ejemplo de Fibonacci pero no pude hacerlo funcionar:

Stream.iterate(new long[]{ 1, 1 }, p->new long[]{ p[1], p[0]+p[1] })
      .limit(92).forEach(p->System.out.println(p[0]));

Solo puedo comenzar en 1.

Esto es lo que intenté hacer:

Stream.iterate(new long[]{ 1 }, p-> {p[0], p[0] + 10})
.limit(4).forEach(p->System.out.println(p[0]));
4
Ido Barash 26 jun. 2017 a las 18:00

3 respuestas

La mejor respuesta

De acuerdo con Stream#iterate documentos del método:

Devuelve una secuencia ordenada secuencial infinita producida por la aplicación iterativa de una función f a un elemento inicial semilla, produciendo una secuencia que consta de semilla, f (semilla), f (f (semilla)), etc.

El primer elemento (posición 0) en la secuencia será la semilla provista. Para n> 0, el elemento en la posición n, será el resultado de aplicar la función f al elemento en la posición n - 1.

Entonces, para su ejemplo, debería funcionar de la siguiente manera:

Stream.iterate(1L, x -> x + 10L)
    .limit(4)
    .forEach(System.out::println); // 1 11 21 31

Si su función es demasiado compleja, puede abstraerla a un método:

private long complexFunction(long value) {
    return <very_complex_calculation with value>;
}

long N = 4L;

Stream.iterate(1L, this::complexFunction)
    .limit(N)
    .forEach(System.out::println);
3
Federico Peralta Schaffner 26 jun. 2017 a las 16:01

Puede usar un AtomicLong para mantener otra variable al iterar. Para la secuencia de Fibonacci donde mantendría el mayor de los 2 números y en AtomicLong y la variable de iteración sería la más pequeña. P.ej.

AtomicLong fibonacci = new AtomicLong(1);
Stream.iterate(1L, x -> fibonacci.getAndAdd(x))
    .limit(10)
    .forEach(i -> System.out.println(fibonacci.get()));
1
Manos Nikolaidis 26 jun. 2017 a las 15:34

Si no te malinterpreto, quieres algo como esto, no necesitas ninguna matriz long[] en absoluto.

LongStream.iterate(1, it -> it + 10).limit(8).forEach(System.out::println);

Para los Integer s puedes usar IntStream#interate en su lugar:

//                         v--- call your math function here
IntStream.iterate(1, it -> math(it, ...)).limit(8).forEach(System.out::println);

O usando LongStream#range en su lugar:

LongStream.range(0,8).map(it -> 10*it + 1).forEach(System.out::println);

Salida

[1, 11, 21, 31, 41, 51, 61, 71]
1
holi-java 26 jun. 2017 a las 15:46