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

如何用Stream groupingBy实现字符串多条件分组并包含默认组?

一步实现多子串匹配分组(含DEFAULT组)

针对你的需求,我们可以通过单流操作完成所有分组逻辑,无需合并多个结果集,同时保证规则可维护性。

最优实现代码

import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class StringGroupingDemo {
    public static void main(String[] args) {
        List<String> strings = List.of("Foo", "FooBar", "FooBarBaz", "XXX");

        // 集中定义分组规则:组名 -> 子串匹配条件
        Map<String, Predicate<String>> groupMatchRules = Map.of(
                "FOO", s -> s.contains("Foo"),
                "BAR", s -> s.contains("Bar"),
                "BAZ", s -> s.contains("Baz")
        );

        Map<String, List<String>> finalResult = strings.stream()
                .flatMap(str -> {
                    // 筛选当前字符串匹配的所有组
                    List<String> matchedGroups = groupMatchRules.entrySet().stream()
                            .filter(entry -> entry.getValue().test(str))
                            .map(Map.Entry::getKey)
                            .toList();

                    // 无匹配组时,映射到DEFAULT;否则映射到所有匹配组
                    return matchedGroups.isEmpty()
                            ? List.of(Map.entry("DEFAULT", str)).stream()
                            : matchedGroups.stream().map(group -> Map.entry(group, str));
                })
                .collect(Collectors.groupingBy(
                        Map.Entry::getKey,
                        // 可选:用LinkedHashMap保证组的顺序与规则定义一致
                        // LinkedHashMap::new,
                        Collectors.mapping(Map.Entry::getValue, Collectors.toList())
                ));

        System.out.println(finalResult);
        // 输出:{FOO=[Foo, FooBar, FooBarBaz], BAR=[FooBar, FooBarBaz], BAZ=[FooBarBaz], DEFAULT=[XXX]}
    }
}

方案优势

  1. 一步完成所有逻辑:从原列表到最终分组结果,仅通过一次流操作实现,避免多次遍历或结果合并
  2. 规则可扩展:新增分组只需在groupMatchRules中添加条目,无需修改流处理逻辑
  3. 逻辑清晰:明确处理每个字符串的多组归属,同时覆盖无匹配的DEFAULT场景

对比原有方案的问题

  • 第一种朴素实现:依赖三元表达式的分支判断,每个字符串只能被分到第一个匹配的组,无法满足"同时进入多个组"的需求
  • 第二种方法:错误地将"Default"作为子串匹配条件(原代码中List.of("Foo", "Bar", "Baz", "Default")),实际逻辑应该是"不匹配前三个规则时进入DEFAULT",导致无法正确生成DEFAULT组

可选优化

如果需要保证输出的组顺序与规则定义一致,可以在groupingBy中指定LinkedHashMap::new作为容器工厂,这样分组顺序会和groupMatchRules的顺序保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 06:09:22