为何while(matcher.find())陷入死循环?基于Stream统计"ei"出现次数
为什么这段Java Stream代码中的while(matcher.find())会无限循环?
问题的核心非常直白:你在while循环的条件里每次都新建了一个Matcher实例——P.matcher(i)会为当前字符串创建一个全新的Matcher对象,而每个新Matcher的匹配起始位置都是字符串的索引0。
也就是说,每次循环判断时,都是从头开始找[Ee]i,永远能找到第一个匹配项,循环根本没有机会终止。比如处理"Einstein"时,每次新建的Matcher都会找到开头的"Ei",count不断累加,但永远不会向后移动匹配位置去查找下一个"ei"(比如字符串中间的"ei"),更别说走到找不到的情况。
修正后的代码
只需要提前创建一次Matcher并复用,让它在循环中自动推进匹配位置:
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( s -> s, s -> { int count = 0; Matcher matcher = P.matcher(s); // 仅创建一次Matcher while (matcher.find()) { count++; } return count; } )); System.out.println(result); }
更简洁的写法
Java 9+还可以用Matcher的results()方法直接统计匹配次数,省去手动循环:
Map<String, Integer> result = L5.stream() .filter(s -> P.matcher(s).find()) .collect(Collectors.toMap( s -> s, s -> (int) P.matcher(s).results().count() ));
内容的提问来源于stack exchange,提问作者Salamantha
相关产品推荐
相关产品推荐

