1. 概述

在Java中统计字符串中某个字符的出现次数有多种实现方式。本文将系统性地介绍这些方法,包括:

  • ✅ 核心Java库原生实现
  • ✅ 主流第三方库(Apache Commons、Guava、Spring)的解决方案
  • ⚠️ 各方案的性能与适用场景分析

面向有经验的Java开发者,我们将直接展示代码实现并对比优劣,避免基础概念赘述。

2. 使用核心Java库

2.1. 命令式方法

最基础的实现方式,通过遍历字符串逐个比较:

String str = "elephant";
char target = 'e';
int count = 0;
 
for (int i = 0; i < str.length(); i++) {
    if (str.charAt(i) == target) {
        count++;
    }
}
assertEquals(2, count);

⚠️ 虽然能解决问题,但代码冗长且不够优雅,现代Java开发中较少使用。

2.2. 递归实现

通过递归分解问题,代码简洁但效率较低:

private static int countWithRecursion(
  String str, char target, int index) {
    if (index >= str.length()) {
        return 0;
    }
    
    int current = str.charAt(index) == target ? 1 : 0;
    return current + countWithRecursion(
      str, target, index + 1);
}

调用示例:countWithRecursion("elephant", 'e', 0)
❌ 递归深度受字符串长度限制,实际项目中应谨慎使用。

2.3. 正则表达式方案

利用正则表达式的匹配能力:

Pattern pattern = Pattern.compile("[^e]*e");
Matcher matcher = pattern.matcher("elephant");
int count = 0;
while (matcher.find()) {
    count++;
}
 
assertEquals(2, count);

⚠️ 技术上可行但属于“杀鸡用牛刀”——简单问题引入复杂工具,影响可读性和性能。

2.4. Java 8+ 新特性

使用Stream API实现函数式风格:

String str = "elephant";
long count = str.chars().filter(ch -> ch == 'e').count();
assertEquals(2, count);

// 处理Unicode补充字符
long count2 = str.codePoints().filter(ch -> ch == 'e').count();
assertEquals(2, count2);

✅ 推荐方案:代码简洁、可读性强,且充分利用现代JVM优化。

3. 使用第三方库

3.1. Apache Commons Lang

引入依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

直接调用工具方法:

int count = StringUtils.countMatches("elephant", "e");
assertEquals(2, count);

✅ 最佳实践:代码极简,经过充分测试,适合生产环境。

3.2. Google Guava

添加依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

使用字符匹配器:

int count = CharMatcher.is('e').countIn("elephant");
assertEquals(2, count);

✅ 链式API设计灵活,适合复杂字符匹配场景。

3.3. Spring Framework

若项目已集成Spring,可直接使用:

import org.springframework.util.StringUtils;

int count = StringUtils.countOccurrencesOf("elephant", "e");
assertEquals(2, count);

⚠️ 仅为统计字符引入Spring框架得不偿失,仅限已有依赖的项目使用。

4. 方案对比与建议

各实现方案关键对比:

实现方式 代码行数 性能 可读性 适用场景
Java 8 Stream 1行 ⭐⭐⭐⭐ 现代Java项目首选
Commons Lang 1行 ⭐⭐⭐⭐ 已引入该库的项目
命令式循环 5行+ ⭐⭐ 无依赖的简单场景
递归 4行 ⭐⭐ 算法演示场景
正则表达式 4行+ 需同时处理复杂匹配时

开发建议:

  1. ✅ 优先使用StringUtils.countMatches()(Apache Commons)或Java 8 Stream
  2. ✅ 已使用Guava的项目选择CharMatcher
  3. ❌ 避免在新项目中使用递归或正则表达式方案
  4. ⚠️ 命令式循环仅作为学习示例,生产环境不推荐

完整示例代码见GitHub仓库(用户名:eugenp,邮箱:dev@example.com


原始标题:Count Occurrences of a Char in a String