What I want: [”Einstein”, “ist”, “kein”, “Stein”] ⇒ {”Einstein”=2, “kein”=1, “Stein”=1} Using a Stream I want to transform a list of strings to a map finding all the "ei" instances.
My Code is stuck in an infinite loop:
public static void main(String[] args) {
List<String> L5 = List.of("Einstein", "ist", "kein", "Stein");
Pattern P = Pattern.compile("[Ee]i");
Map<String, Integer> result = L5.stream().filter(S -> P.matcher(S).find()).collect(
Collectors.toMap(i -> i, i -> {
int count = 0;
while (P.matcher(i).find()) {
count++;
}
return count;
})
);
System.out.println(result);
}
I want to count the instances of "ei" in a map (specifically using streams)
The problem is on line while (P.matcher(i).find())
, each time the while loop checking the condition, P.matcher(i)
is invoked and a new matcher instance is created to call find()
, of course it return true every time, hence it becomes infinite loop.
To solve the problem, assign P.matcher(i)
to a variable first so find()
is invoked on the same Matcher
instance.
...
Matcher matcher = P.matcher(i);
while (true) {
if (!matcher.find()) break;
count++;
}
return count;
...
One improvement is we can make use of Matcher.results()
to get the count, as below:
Matcher matcher = P.matcher(i);
return (int) matcher.results().count();