为什么我的 while(matcher.find()) 进入了无限循环?我在流(Streams)中使用它。

huangapple go评论135阅读模式
英文:

Why is my while(matcher.find()) entering an infinite loop? I use it in with Streams

问题

我想要计算在地图中的 "ei" 实例次数(特别是使用流)。

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);
}

这段代码中,它使用流来转换字符串列表为一个地图,并计算 "ei" 出现的次数。

英文:

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&lt;String&gt; L5 = List.of(&quot;Einstein&quot;, &quot;ist&quot;, &quot;kein&quot;, &quot;Stein&quot;);
  Pattern P = Pattern.compile(&quot;[Ee]i&quot;);
  Map&lt;String, Integer&gt; result = L5.stream().filter(S -&gt; P.matcher(S).find()).collect(
    Collectors.toMap(i -&gt; i, i -&gt; {
      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)

答案1

得分: 2

问题出在代码的这一行:while (P.matcher(i).find()),每次循环检查条件时,都会调用P.matcher(i)并创建一个新的匹配器实例来调用find(),当然,它每次都返回true,因此变成了一个无限循环。

为了解决这个问题,首先将P.matcher(i)分配给一个变量,以便在同一个Matcher实例上调用find()

...
Matcher matcher = P.matcher(i);
while (true) {
    if (!matcher.find()) break;
    count++;
}
return count;
...

一个改进是我们可以利用Matcher.results()来获取计数,如下所示:

Matcher matcher = P.matcher(i);
return (int) matcher.results().count();
英文:

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();

huangapple
  • 本文由 发表于 2023年2月23日 22:01:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75545823.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定