4

How do you create stream of Boolean.FALSE, say, length of 100?

What I've struggled with is:

  1. Originally I've intended to create an array of Boolean.FALSE. But new Boolean[100] returns an array of NULL. So reasonably I considered to use stream API as a convenient Iterable and almost (1) Iterable manipulation tool;
  2. There is no Boolean no-params constructor (2), hence I can't use Stream.generate(), since it accepts Supplier<T> (3).

What I found is Stream.iterate(Boolean.FALSE, bool -> Boolean.FALSE).limit(100); gives what I want, but it doesn't seem to be quite elegant solution, IMHO.

One more option, I found (4) is IntStream.range(0, 100).mapToObj(idx -> Boolean.FALSE);, which seems to me even more strange.

Despite these options don't violate pipeline conception of a stream API, are there any more concise ways to create stream of Boolean.FALSE?

Alexis C.
  • 91,686
  • 21
  • 171
  • 177
Evgeny Mamaev
  • 1,237
  • 1
  • 14
  • 31
  • 4
    Why do you think you cannot use `Stream.generate()`? Try this: `Stream.generate(() -> Boolean.FALSE).limit(100)` – Jesper Oct 16 '17 at 09:51
  • 2
    I can’t imagine any reasonable use case for such a stream. If you follow the recommended usage of only using stateless functions, i.e. do not depend on the processing order, the result can always only be a stream of hundred identical elements or an empty stream. Whatever the final result will be, it would always be possible to generate it from a single element stream instead. – Holger Oct 16 '17 at 11:33
  • @Holger I detect cycles on undirected graph. One of the steps needs to be performed is detection of parallel edges. I mark every vertex I visited to detect parallelism. So each vertex has a match in the array of "is visited". After the iteration is completed, the array of "is visited" should be reset. And here I let such a stream play. I could use an array of 0 and 1 for this purpose, but for clarity sake decided to use what I used. – Evgeny Mamaev Oct 16 '17 at 12:25
  • 1
    Thanks for trying to explain, but I still can’t image, how you want to use 100 `false` constants in a useful way. You are talking about an array in your explanation, but a stream is not an array. It doesn’t work like an array. In that regard, it didn’t matter if you used a stream of 100 zeros as starting point, they were as meaningless as 100 `false` constants. If you need a boolean array initialized with `false`, you could create it as easy as `new boolean[100]` without the need for a stream. – Holger Oct 16 '17 at 12:36
  • @Holger the exact reason I decided to use a stream is my may be naive intention to iterate over the array with its help. As you precisely noticed, and I totally agree with you, I could simply use `new boolean[100]`. And then iterate through it with a loop. But a big question still floats in my mind. When is it worthwhile to prefer a stream over a loop to iterate through things?) – Evgeny Mamaev Oct 16 '17 at 13:11
  • 2
    That’s not easy to answer, you’ll need some experience to decide. And not everyone will have the same opinion. As a rule of thumb, if the processing of each element is independent from each other (or its position) and the resulting code is simpler than the loop’s code or allows to do more complex things (in an easy way) than before. Or if there’s a reasonable expectation to get a benefit from parallel processing (which makes independence of the processing order even more important). – Holger Oct 16 '17 at 13:18
  • 1
    If this is all to initialize an array to a value, you can just use [`java.util.Arrays.fill`](https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#fill-java.lang.Object:A-java.lang.Object-), no streams necessary. `Arrays.fill(array, Boolean.FALSE);` – Sean Van Gorder Oct 17 '17 at 16:53

3 Answers3

9

Even though Boolean has no no-arg constructor, you can still use Stream.generate using a lambda:

Stream.generate(() -> Boolean.FALSE).limit(100)

This also has the advantage (compared to using a constructor) that those will be the same Boolean instances, and not 100 different but equal ones.

tobias_k
  • 81,265
  • 12
  • 120
  • 179
7

You can use Collections's static <T> List<T> nCopies(int n, T o):

Collections.nCopies (100, Boolean.FALSE).stream()...

Note that the List returned by nCopies is tiny (it contains a single reference to the data object)., so it doesn't require more storage compared to the Stream.generate().limit() solution, regardless of the required size.

Eran
  • 387,369
  • 54
  • 702
  • 768
1

of course you could create the stream directly

Stream.Builder<Boolean> builder = Stream.builder();
for( int i = 0; i < 100; i++ )
  builder.add( false );
Stream<Boolean> stream = builder.build();
Kaplan
  • 2,572
  • 13
  • 14