5

I'm learning about stream expressions and trying to use them to construct a 2D boolean array, with all values set to true. Something like:

boolean[][] bool_array = [stream expression returning a
                             2D array boolean[h][w], all values set to true]

Is this possible to do and what would the expression be?

I know int[][] arrays may be created using streams, for example

int h=5;
int w=8;
int[][] int_array = IntStream.range(0,h).mapToObj(i->IntStream.range(0,w).
          map(j->1).toArray()).toArray(int[][]::new);

returns an int[5][8] filled with ones. But trying to get this to work for boolean[][]

boolean[][] bool_array = IntStream.range(0,h).mapToObj(i->IntStream.range(0,w).
          mapToObj(j->true).toArray()).toArray(boolean[][]::new);

throws an ArrayStoreException.

Robb Hoff
  • 1,719
  • 2
  • 17
  • 32
  • 2
    Reasonably one could say it's not clear what you're asking--your title or what's wrong with your code--because continuously people ask re debugging like this muddled with asking how to code their overall goal so it's not surprising readers would take this that way. If the question's the title & you haven't debugged that then you haven't finished sufficient research--downvote but not close vote--& if you're asking re debugging then that's not clear & you don't give a [mre]--both votes. PS When you get results you don't understand, put things on hold & find out what you don't understand. – philipxy Oct 11 '20 at 03:29
  • @philipxy I took this to mean that you thought I was close, and it seems you would be right. I found a solution that was almost exactly what I had – Robb Hoff Oct 11 '20 at 09:01
  • 1
    Glad you found a solution. I didn't have an opinion on whether you were close. I just meant what I said, which I thought was clear. PS You haven't edited to mitigate the kind of reasonable interpretation as unclear I mentioned. (As I said,) Code that seems not understood by the poster looks too much like a request to debug & doesn't serve as an example of what was tried because it needs debugging first. PS A solution (to whatever the question is) really should be in an answer post not the question. – philipxy Oct 11 '20 at 09:24
  • 1
    @philipxy I understand you think this is unclear and that you interpret it as needing debugging. I do **not**. I do not think the post is asking for any debugging **at all**. It's clear to me that they want a two dimensional `boolean` array. They've tried with a two dimensional `int` array which worked, but didn't work for `boolean` and now want to know if it's possible. – Scratte Oct 11 '20 at 11:44
  • 1
    `Stream.toArray()` returns an `Object[]` which cannot be cast to `boolean[]`, so that doesn't work. You also cannot use `Stream.toArray(boolean[]::new)` on your "inner" result, as `boolean` is a primitive and cannot be used as a variable for a generic parameter type. It works for `int` because `IntStream` has an inbuilt method to create an `int[]`. As you've discovered it works for `Boolean[][]` since `Boolean` can be used as a variable for a generic parameter, but that still doesn't get you a `boolean[][]` – Scratte Oct 11 '20 at 12:03
  • @Scratte I didn't say I ithought it was unclear and/or asking for debugging. I said you can expect people to reasonably do so. I also said that it's poor writing to give code needing debugging as an example of what they tried because it isn't. They know the code didn't run, but they don't know whether whatever they were trying to do with it worked until they know why the code didn't run. If they understand that something can't be done, by coming to know more about the language by understanding some code they didn't know wouldn't run, they should say so, not dump code they don't understand. – philipxy Oct 11 '20 at 21:40
  • 4
    @Gimby I think OP had plenty of time to take action on your comment, but chose not to. Therefore I rolled the question back to the revision before the answer was added. – Luuklag Oct 13 '20 at 12:29
  • I've posted my answer separately like suggested. Note the comments by @Scratte refer to this answer – Robb Hoff Oct 13 '20 at 18:37
  • Similar ? https://stackoverflow.com/questions/7118178/arrays-fill-with-multidimensional-array-in-java – Eklavya Oct 15 '20 at 06:38

3 Answers3

4

If you want to do it with streams you can do it like this:

int rows = 5;
int cols = 5;

boolean[][] bool2D = IntStream.range(0, rows)
        .mapToObj(r -> {
            boolean[] rr;
            Arrays.fill(rr = new boolean[cols], true);
            return rr;
        }).toArray(boolean[][]::new);


for (boolean[] b : bool2D) {
    System.out.println(Arrays.toString(b));
}

Prints

[true, true, true, true, true]
[true, true, true, true, true]
[true, true, true, true, true]
[true, true, true, true, true]
[true, true, true, true, true]
WJS
  • 36,363
  • 4
  • 24
  • 39
  • ...and this is preferable to a loop because...? You don't get concurrency or threading here. – Makoto Oct 09 '20 at 22:11
  • 15
    I never said or even implied it was preferable. I was simply answering the OP's question without being judgmental about it. – WJS Oct 09 '20 at 22:33
  • I have played with `java.util.stream.Stream` - so many times and attempted so many different versions of code that has it. Half the work of learning **Java** turns into figuring out exactly what you are supposed to do with a **Stream**. I eventually settled on using the `Stream.Builder` and `IntStream.Builder` to makes lists (quickly) of things.. It's **always good** to see if a `Stream` can be used (and if it makes the code uglier or better) – Y2020-09 Oct 11 '20 at 02:36
1

I've discovered a way to make a Boolean[][] array (that is, the Object type boolean, not the primitive type). The line is almost the same as the one in my question, but with a cast to Boolean[] in the first toArray()

Boolean[][] bool_array = IntStream.range(0,h).mapToObj(i->IntStream.range(0,w).
           mapToObj(j->true).toArray(Boolean[]::new)).toArray(Boolean[][]::new);
Robb Hoff
  • 1,719
  • 2
  • 17
  • 32
-5

It's more expedient to use a loop. Lambda statements and streams do not fundamentally replace loops, and the simplicity you get with using loops in this context is far simpler and far easier to deal with.

Note that my answer is also based in learning about lambda expressions. When they first came out, I too thought they could do a lot of things that loops could. However, learning a new tool or approach also includes learning when not to use it, and general iteration is definitely not a circumstance when lambdas are fit for purpose.

Makoto
  • 104,088
  • 27
  • 192
  • 230