8

I would like to count occurrences of a character (for example the space: ' ' ) in 2D Array, using stream. I was trying to find a solution. Here is my code, using a nested loops:

public int countFreeSpaces() {
    int freeSpaces = 0;
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            if (board[j][i] == ' ') freeSpaces++;
        }
    }
    return freeSpaces;
}
MarianD
  • 13,096
  • 12
  • 42
  • 54
cerbin
  • 1,180
  • 15
  • 31

2 Answers2

9

I believe this answer is slightly more expressive:

int freeSpaces = (int) Arrays.stream(board)
                             .map(CharBuffer::wrap)
                             .flatMapToInt(CharBuffer::chars)
                             .filter(i -> i == ' ')
                             .count();
Jacob G.
  • 28,856
  • 5
  • 62
  • 116
  • 6
    Good approach, though I’d use `Arrays.stream` to stream over an existing array instead of the varargs method `Stream.of`. Also, `String::new` implies copying the `char[]` data, so I’d use `.map(CharBuffer::wrap) .flatMapToInt(CharSequence::chars)` instead. Contrary to what we might expect, in Java 8, `CharBuffer.chars()` is even implemented more efficient than `String.chars()`. – Holger Jul 13 '17 at 14:50
  • 2
    first, up-vote. due to I write down the answer I don't know the OP is whether using a `char[]` or a `Character[]`, so I used `IntStream` instead. as you can see my answer publish time is before the OP says its type is a `char[]`. – holi-java Jul 13 '17 at 15:07
  • 1
    @Holger Thank you very much for your insight! I'll change the answer around. – Jacob G. Jul 13 '17 at 15:10
2

How about this?

//                      v--- create a Stream<char[]>             
int spaces = (int) Stream.of(board)
                          .flatMapToInt(cells->IntStream.range(0, cells.length)
                          .filter(i -> cells[i] == ' '))
                          .count();
cerbin
  • 1,180
  • 15
  • 31
holi-java
  • 29,655
  • 7
  • 72
  • 83
  • :), why is wrong? I don't understand it. could anyone tell me why before I delete the answer? thanks. I'm not good at English. – holi-java Jul 13 '17 at 14:24
  • That works fine, was expecting that it will be like shorter but it is easy to read. – cerbin Jul 13 '17 at 14:26
  • @cerbin if you remove the comments and inline, you can find that will be shorter and expressive. – holi-java Jul 13 '17 at 14:29
  • That is fine, these indentation increases readability. However, In my opinion these comments you made are not necessary, words from java like count() tells enough. – cerbin Jul 13 '17 at 14:31
  • @cerbin okay. I'll remove the comments later. – holi-java Jul 13 '17 at 14:33