如何用Java 8的Stream、GroupBy实现字符流分组并输出连续字符计数结果
Java 8 Stream 实现连续字符频次统计
输入:aaabbaaeedddbbbb
输出:a3b2a2e2d3b4
要求使用Java 8的Stream、GroupBy相关特性实现。
实现思路
- 核心难点:常规
groupingBy会全局聚合所有相同字符,无法区分连续分段的相同字符,因此需要给每个连续字符段分配唯一的分组ID - 具体逻辑:
- 遍历字符串每个字符,同步记录前一个字符和当前分组ID
- 若当前字符与前一个字符不同,分组ID自增,进入新的连续段
- 按照分组ID做
groupingBy聚合,统计每个分组的字符和出现次数 - 按分组顺序拼接「字符+次数」得到最终结果
完整实现代码
import java.util.AbstractMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; public class ContinuousCharCount { public static void main(String[] args) { String input = "aaabbaaeedddbbbb"; String result = countContinuousChar(input); System.out.println(result); // 输出结果:a3b2a2e2d3b4 } private static String countContinuousChar(String input) { // 空串直接返回 if (input == null || input.isEmpty()) { return ""; } // 存储前一个字符,用于判断是否进入新连续段 AtomicReference<Character> prevChar = new AtomicReference<>(null); // 连续段分组ID,不同连续段ID唯一 AtomicInteger groupId = new AtomicInteger(0); return input.chars() // int转Character类型 .mapToObj(c -> (char) c) // 给每个字符绑定所属的连续段ID .map(c -> { Character prev = prevChar.getAndSet(c); if (prev == null || !prev.equals(c)) { groupId.incrementAndGet(); } return new AbstractMap.SimpleEntry<>(groupId.get(), c); }) // 按连续段ID分组 .collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey)) // 按分组顺序处理每组数据 .values() .stream() .map(list -> list.get(0).getValue() + String.valueOf(list.size())) .collect(Collectors.joining()); } }
内容的提问来源于stack exchange,提问作者Malleswar Reddy
相关产品推荐
相关产品推荐

