Reputation: 3750
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?
Upvotes: 0
Views: 1521
Reputation: 56499
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();
Upvotes: 2
Reputation: 18588
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
.
Upvotes: 1
Reputation: 1687
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();
Upvotes: 2