You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Java 8统计字符串中连续字符的出现次数?

Java 8实现连续字符计数

要在Java 8中实现连续字符的出现次数统计,核心是利用流式操作结合状态跟踪——因为需要按顺序处理每个字符,记录当前连续字符的计数。以下是两种可行的实现方式:

方法一:用IntStream.collect直接操作StringBuilder

这种方式直接在收集器里维护StringBuilder,每次处理字符时判断是否与前一个字符相同,动态修改或追加内容:

String str = "aabbbccddbb";

String result = IntStream.range(0, str.length())
    .collect(StringBuilder::new, (sb, index) -> {
        char currentChar = str.charAt(index);
        if (index == 0) {
            // 第一个字符,直接初始化计数和字符
            sb.append(1).append(currentChar);
        } else {
            char prevChar = str.charAt(index - 1);
            if (currentChar == prevChar) {
                // 字符连续,找到最后面的数字部分并递增
                int lastDigitStart = sb.length() - 1;
                while (lastDigitStart >= 0 && Character.isDigit(sb.charAt(lastDigitStart))) {
                    lastDigitStart--;
                }
                String countStr = sb.substring(lastDigitStart + 1);
                int newCount = Integer.parseInt(countStr) + 1;
                // 替换原数字为递增后的结果
                sb.replace(lastDigitStart + 1, sb.length(), String.valueOf(newCount));
            } else {
                // 字符不连续,追加新的计数和字符
                sb.append(1).append(currentChar);
            }
        }
    }, StringBuilder::append)
    .toString();

System.out.println(result); // 输出:2a3b2c2d2b

方法二:用reduce自定义状态对象

通过自定义状态类保存当前字符、计数和结果缓冲区,利用reduce累积状态,状态管理更清晰:

// 定义状态类,跟踪当前连续字符的计数和结果
static class ContinuousCharCount {
    char currentChar;
    int count;
    StringBuilder resultBuffer = new StringBuilder();
}

public static void main(String[] args) {
    String str = "aabbbccddbb";
    
    if (str.isEmpty()) {
        System.out.println("");
        return;
    }

    ContinuousCharCount finalState = IntStream.range(0, str.length())
        .reduce(new ContinuousCharCount(), (state, index) -> {
            char c = str.charAt(index);
            if (index == 0) {
                // 初始化第一个字符的状态
                state.currentChar = c;
                state.count = 1;
            } else {
                if (c == state.currentChar) {
                    // 字符连续,计数递增
                    state.count++;
                } else {
                    // 字符中断,将当前累积结果写入缓冲区
                    state.resultBuffer.append(state.count).append(state.currentChar);
                    // 更新状态为新字符
                    state.currentChar = c;
                    state.count = 1;
                }
            }
            return state;
        }, (state1, state2) -> {
            // 并行流场景的合并逻辑(串行流可简化,但保留更健壮)
            if (state1.resultBuffer.length() == 0) {
                return state2;
            }
            if (state2.resultBuffer.length() == 0) {
                state1.resultBuffer.append(state2.count).append(state2.currentChar);
                return state1;
            }
            // 检查首尾字符是否连续,连续则合并计数
            char lastCharOfState1 = state1.currentChar;
            char firstCharOfState2 = state2.currentChar;
            if (lastCharOfState1 == firstCharOfState2) {
                state1.count += state2.count;
                state1.resultBuffer.append(state2.resultBuffer.substring(state2.resultBuffer.indexOf(String.valueOf(firstCharOfState2)) + 1));
            } else {
                state1.resultBuffer.append(state1.count).append(state1.currentChar);
                state1.resultBuffer.append(state2.resultBuffer);
            }
            return state1;
        });

    // 写入最后一组连续字符的结果
    finalState.resultBuffer.append(finalState.count).append(finalState.currentChar);
    System.out.println(finalState.resultBuffer.toString()); // 输出:2a3b2c2d2b
}

注意事项

  • 两种方式都处理了空字符串和单个字符的边界情况;
  • 方法一代码紧凑,但修改StringBuilder的操作相对繁琐;方法二状态管理更清晰,适合扩展复杂逻辑;
  • 若不需要并行处理,可简化reduce的第三个合并参数,但保留它能让代码更健壮。

内容的提问来源于stack exchange,提问作者Deepak Ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 22:53:12