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

Apex中含可选变量的Map规则匹配优化方案咨询

多可选字段Map匹配的优雅实现方案

针对你在Apex开发中遇到的多变量Map匹配问题,这里提供两种简洁易维护的实现思路,彻底消除冗余的if-else判断:


核心思路

核心是按优先级生成所有可能的匹配键组合(从全字段匹配到最宽松的部分匹配),查询时依次尝试这些键,找到第一个存在的Map值。优先级规则为:非空匹配字段越多,优先级越高;同数量匹配字段时,按预设的字段权重排序(比如field1 > field2 > field3 > field4)。


方案一:字符串拼接键(轻量高效)

适合字段值不含自定义分隔符的场景,实现简单性能优。

1. 预生成优先级匹配模式(缓存复用)

通过位掩码生成所有匹配模式,并按优先级排序,只需初始化一次:

private static List<List<Boolean>> cachedPatterns;
static {
    cachedPatterns = new List<List<Boolean>>();
    // 4个字段生成2^4=16种模式
    for (Integer mask = 0; mask < 16; mask++) {
        cachedPatterns.add(new List<Boolean>{
            (mask & 8) != 0, // field1 对应最高位
            (mask & 4) != 0, // field2
            (mask & 2) != 0, // field3
            (mask & 1) != 0  // field4 对应最低位
        });
    }
    // 按匹配字段数量降序、字段权重升序排序
    cachedPatterns.sort((a, b) -> {
        Integer countA = a.count(true);
        Integer countB = b.count(true);
        if (countA != countB) return countB - countA;
        // 同数量时,优先保留权重高的字段匹配
        for (Integer i = 0; i < 4; i++) {
            if (a[i] != b[i]) return a[i] ? 1 : -1;
        }
        return 0;
    });
}

2. 生成匹配键

根据查询参数和模式生成对应的拼接键:

private static String generateKey(String f1, String f2, String f3, String f4, List<Boolean> pattern) {
    List<String> parts = new List<String>();
    if (pattern[0]) parts.add(f1 ?? '');
    if (pattern[1]) parts.add(f2 ?? '');
    if (pattern[2]) parts.add(f3 ?? '');
    if (pattern[3]) parts.add(f4 ?? '');
    return String.join(parts, '::'); // 用分隔符避免字段值冲突
}

3. 查询逻辑

遍历优先级模式,找到第一个匹配的Map值:

public static Object getMatchedValue(Map<String, Object> configMap, String f1, String f2, String f3, String f4) {
    for (List<Boolean> pattern : cachedPatterns) {
        String key = generateKey(f1, f2, f3, f4, pattern);
        if (configMap.containsKey(key)) {
            return configMap.get(key);
        }
    }
    return null;
}

方案二:Wrapper类键(类型安全)

适合字段值可能包含特殊字符、或字段类型复杂的场景,避免拼接冲突。

1. 定义MatchKey类(重写equals和hashCode)

public class MatchKey {
    public String field1;
    public String field2;
    public String field3;
    public String field4;

    public MatchKey(String f1, String f2, String f3, String f4) {
        this.field1 = f1;
        this.field2 = f2;
        this.field3 = f3;
        this.field4 = f4;
    }

    // 匹配规则:非空字段必须完全相等,空字段适配所有值
    public Boolean equals(Object obj) {
        if (obj == null || !(obj instanceof MatchKey)) return false;
        MatchKey other = (MatchKey) obj;
        return (this.field1 == other.field1 || (this.field1 != null && this.field1.equals(other.field1))) &&
               (this.field2 == other.field2 || (this.field2 != null && this.field2.equals(other.field2))) &&
               (this.field3 == other.field3 || (this.field3 != null && this.field3.equals(other.field3))) &&
               (this.field4 == other.field4 || (this.field4 != null && this.field4.equals(other.field4)));
    }

    public Integer hashCode() {
        Integer hash = 0;
        if (field1 != null) hash ^= field1.hashCode();
        if (field2 != null) hash ^= field2.hashCode();
        if (field3 != null) hash ^= field3.hashCode();
        if (field4 != null) hash ^= field4.hashCode();
        return hash;
    }
}

2. 生成查询用的优先级键列表

private static List<MatchKey> generateQueryKeys(String f1, String f2, String f3, String f4) {
    List<MatchKey> keys = new List<MatchKey>();
    for (Integer mask = 0; mask < 16; mask++) {
        keys.add(new MatchKey(
            (mask & 8) != 0 ? f1 : null,
            (mask & 4) != 0 ? f2 : null,
            (mask & 2) != 0 ? f3 : null,
            (mask & 1) != 0 ? f4 : null
        ));
    }
    // 按匹配字段数量降序排序
    keys.sort((a, b) -> {
        Integer countA = (a.field1 != null ? 1 : 0) + (a.field2 != null ? 1 : 0) + (a.field3 != null ? 1 : 0) + (a.field4 != null ? 1 : 0);
        Integer countB = (b.field1 != null ? 1 : 0) + (b.field2 != null ? 1 : 0) + (b.field3 != null ? 1 : 0) + (b.field4 != null ? 1 : 0);
        return countB - countA;
    });
    return keys;
}

3. 查询逻辑

public static Object getMatchedValue(Map<MatchKey, Object> configMap, String f1, String f2, String f3, String f4) {
    for (MatchKey key : generateQueryKeys(f1, f2, f3, f4)) {
        if (configMap.containsKey(key)) {
            return configMap.get(key);
        }
    }
    return null;
}

方案优势

  1. 彻底消除冗余if-else:所有匹配逻辑通过动态生成的优先级模式实现,代码简洁易维护。
  2. 扩展性强:字段数量变化时,只需调整位掩码范围(比如5个字段则mask从0到31),无需修改核心逻辑。
  3. 优先级可控:排序规则可根据业务需求灵活调整,确保匹配顺序符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:57:08