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; }
方案优势
- 彻底消除冗余if-else:所有匹配逻辑通过动态生成的优先级模式实现,代码简洁易维护。
- 扩展性强:字段数量变化时,只需调整位掩码范围(比如5个字段则mask从0到31),无需修改核心逻辑。
- 优先级可控:排序规则可根据业务需求灵活调整,确保匹配顺序符合预期。
内容的提问来源于stack exchange,提问作者kryptt
相关产品推荐
相关产品推荐

