0

Hi i want to count how many time a String is found in a Array of Strings using Streams

What i have thought so far is this:

Stream<String> stream=Arrays.stream(array);

int counter= (int) stream.filter(c-> c.contains("something")).count();

return counter;

The problem that i get is that most of the time i get an error of NullPointerException and i think is because of .count() if it doesn't get any much inside filter(c-> c.contains("something")). And i came to this conclusion cause if i run it with out .count() like that stream.filter(c-> c.contains("something")); without returning nothing, it won't throw an Exception. I'm not sure about it but that's what i think.

Any ideas on how i can count the times a String appears in and Array of Strings using Streams?

4
  • 2
    "i came to this conclusion cause if i run it with out .count() it won't throw an Exception" that's because without count the pipeline is not executed. streams are lazy. my bet would be on c i.e. the elements inside the array. you're better off showing the stack trace to better explain your issue. Commented May 28, 2020 at 13:01
  • where does array come from? it looks the problem is from that. Commented May 28, 2020 at 13:03
  • Why are you casting the result to an int? Doesn't long meet your requirements? However, you can add a second filter that does .filter(java.util.Objects::nonNull) before the filter you already have applied. Commented May 28, 2020 at 13:07
  • @MajidRoustaei if we're to go by what the OP said i.e. the code doesn't throw NullPointerException when count is not called then what you've just suggested is not the culprit. see my answer for more info on that. Commented May 28, 2020 at 13:56

3 Answers 3

2

null is a valid element of an array, so you have to be prepared to handle these. For example:

int counter = stream.filter(c -> c != null && c.contains("something")).count();
Sign up to request clarification or add additional context in comments.

2 Comments

don't forget the cast to (int) or change to stream.filter(c -> c != null && c.contains("something")).mapToInt(v -> 1).sum();
on another note i agree that a null is a valid element of an array but whether null is valid in this context is something only the application author can answer as maybe nulls should not be in the array in the first place at which point it would be better to find the bug rather than suppress it.
2

The problem that i get is that most of the time i get an error of NullPointerException and i think is because of .count() And i came to this conclusion cause if i run it with out .count() it won't throw an Exception.

The reason being you cannot replicate the NullPointerException without calling count is because streams are lazy evaluated i.e. the entire pipeline is not executed until an eager operation (an operation which triggers the processing of the pipeline) is invoked.

We can come to the conclusion that Arrays.stream(array) is not the culprit for the NullPointerException because it would have blown up regardless of wether you called an eager operation on the stream or not as the parameter to Arrays.stream should be nonNull or else it would bomb out with the aforementioned error.

Thus we can come to the conclusion that the elements inside the array are the culprits for this error in the code you've illustrated but then you should ask your self are null elements allowed in the first place and if so then filter them out before performing c.contains("something") and if not then you should debug at which point in your application were nulls added to the array when they should not be. find the bug rather than suppress it.

if null's are allowed in the first place then the solution is simple i.e. filter the nulls out before calling .contains:

int counter = (int)stream.filter(Objects::nonNull)
                         .filter(c -> c.contains("something")) // or single filter with c -> c != null && c.contains("something") as pred
                         .count();

3 Comments

You are right , null elements was the problem. I accepted the the other answer just because it was written earlier. Thanks a lot all of you.
@Panagiss yes null elements was the problem but what's more important is should you be suppressing the nulls or should you be finding out why nulls were in the array in the first place. either choice is valid if that's what your system deems. just make sure you're taking the right approach in terms of fixing the problem hence my elaborative answer.
Yeah i see what are you talking about. I should make a plan and fix some other stuff in order to make my array null-free.
1

You have to filter for null values first. Do it either the way @pafauk. answered or by filtering sepraretly. That requires the null filter to be applied before the one you already use:

public static void main(String[] args) {
    List<String> chainedChars = new ArrayList<>();
    chainedChars.add("something new");  // match
    chainedChars.add("something else"); // match
    chainedChars.add("anything new");
    chainedChars.add("anything else");
    chainedChars.add("some things will never change");
    chainedChars.add("sometimes");
    chainedChars.add(null);
    chainedChars.add("some kind of thing");
    chainedChars.add("sumthin");
    chainedChars.add("I have something in mind");   // match
    chainedChars.add("handsome thing");

    long somethings = chainedChars.stream()
                                    .filter(java.util.Objects::nonNull)
                                    .filter(cc -> cc.contains("something"))
                                    .count();

    System.out.printf("Found %d somethings", somethings);
}

outputs

Found 3 somethings

while switching the filter lines will result in a NullPointerException.

2 Comments

thanks a lot for the help, You are right , null elements was the problem. I accepted the the other answer just because it was written earlier. Thanks
@Panagiss no problem! I voted it up, it was posted earlier and my answer just provides a different way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.