Reputation: 57
In ruby you can do something like this
a = ["a", "b", "c"]
a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
a.cycle(2) {|x| puts x } # print, a, b, c, a, b, c.
and this is just beautiful.
The closest analog in Java 8 would be like this:
Stream<Integer> iterator = Stream.iterate(new int[] {0, 0}, p -> new int[]{p[0] + 1, (p[0] + 1) % 2}).map(el -> el[1]);
Iterator<Integer> iter = iterator.iterator();
System.out.println(iter.next());//0
System.out.println(iter.next());//1
System.out.println(iter.next());//0
System.out.println(iter.next());//1
Is there a better way and more idiomatic to do it in Java?
Update
Just want to outline here that the closest solution to my problem was
IntStream.generate(() -> max).flatMap(i -> IntStream.range(0, i))
Thanks to @Hogler
Upvotes: 4
Views: 209
Reputation: 3974
Well if you define the array variable outside the stream, you can use indexes instead. And you will have something like:
String[] array = { "a", "b", "c" };
Stream.iterate(0, i -> (i + 1) % array.length)
.map(i -> array[i])
.forEach(System.out::println); // prints a, b, c forever
Stream.iterate(0, i -> (i + 1) % array.length)
.map(i -> array[i])
.limit(2 * array.length)
.forEach(System.out::println); // prints a, b, c 2 times
Also can use nCopies you don't need to use array.length
:
Collections.nCopies(2, array).stream()
.flatMap(Arrays::stream)
.forEach(System.out::println); // prints a, b, c 2 times
It is obviously longer than the ruby version, but that's how usually java is (more verbose)
Upvotes: 3
Reputation: 298439
You may use
String[] array = { "a", "b", "c" };
Stream.generate(() -> array).flatMap(Arrays::stream).forEach(System.out::println);
to print a
b
c
forever and
String[] array = { "a", "b", "c" };
Stream.generate(() -> array).limit(2).flatMap(Arrays::stream).forEach(System.out::println);
to print a
b
c
two times.
This doesn’t even require an existing array:
Stream.generate(() -> null)
.flatMap(x -> Stream.of("a", "b", "c"))
.forEach(System.out::println);
resp.
Stream.generate(() -> null).limit(2)
.flatMap(x -> Stream.of("a", "b", "c"))
.forEach(System.out::println);
you could also use
IntStream.range(0, 2).boxed()
.flatMap(x -> Stream.of("a", "b", "c"))
.forEach(System.out::println);
Upvotes: 5