Java中List.contains无法匹配含额外字符的目标值的解决方法
解决方案
要实现实际数据字符串包含可选值子串的匹配与计数,核心思路是遍历实际数据,对每个字符串检查是否包含任意可选值,并维护计数。以下是两种可行方案:
1. 基础遍历实现(适合小规模数据)
用HashMap存储每个可选值的计数,遍历实际数据列表,对每个字符串逐一检查是否包含可选值列表中的元素,匹配成功则对应计数+1。
代码示例:
import java.util.*; public class SubstringMatchCounter { public static void main(String[] args) { List<String> optionalValues = Arrays.asList("Halle 1", "Halle 2", "Halle 3"); List<String> actualData = Arrays.asList( "Vor Halle 1", "Halle 1, Montage", "Halle 2 und Halle 1", "Keine Übereinstimmung" ); // 初始化计数Map,默认值为0 Map<String, Integer> countMap = new HashMap<>(); for (String value : optionalValues) { countMap.put(value, 0); } // 遍历实际数据,统计匹配次数 for (String data : actualData) { for (String target : optionalValues) { if (data.contains(target)) { countMap.put(target, countMap.get(target) + 1); } } } // 输出结果 for (Map.Entry<String, Integer> entry : countMap.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue() + " 次"); } } }
输出结果:
Halle 1: 3 次 Halle 2: 2 次 Halle 3: 0 次
2. 正则表达式优化(适合大规模数据)
如果实际数据或可选值列表规模较大,逐一匹配会有性能瓶颈。可以将所有可选值拼接成一个正则表达式,一次性匹配字符串中的所有目标子串,减少遍历次数。注意要对可选值中的正则特殊字符(如.、*、+等)进行转义。
代码示例:
import java.util.*; import java.util.regex.*; public class RegexMatchCounter { public static void main(String[] args) { List<String> optionalValues = Arrays.asList("Halle 1", "Halle 2", "Halle 3"); List<String> actualData = Arrays.asList( "Vor Halle 1", "Halle 1, Montage", "Halle 2 und Halle 1", "Keine Übereinstimmung" ); // 转义可选值中的正则特殊字符,拼接成正则表达式 String regexPattern = optionalValues.stream() .map(Pattern::quote) .reduce((a, b) -> a + "|" + b) .orElse(""); Pattern pattern = Pattern.compile(regexPattern); // 如需忽略大小写,使用Pattern.compile(regexPattern, Pattern.CASE_INSENSITIVE) Map<String, Integer> countMap = new HashMap<>(); optionalValues.forEach(v -> countMap.put(v, 0)); for (String data : actualData) { Matcher matcher = pattern.matcher(data); // 用Set确保同一字符串中同一目标只计一次,若需统计出现总次数可直接计数 Set<String> matchedValues = new HashSet<>(); while (matcher.find()) { matchedValues.add(matcher.group()); } matchedValues.forEach(v -> countMap.put(v, countMap.get(v) + 1)); } // 输出结果 countMap.forEach((k, v) -> System.out.println(k + ": " + v + " 次")); } }
注意事项
- 如果需要避免部分误匹配(比如防止"Halle 10"被识别为包含"Halle 1"),可以在正则中添加边界逻辑,比如
\b(单词边界),但要注意目标字符串中的非单词字符(如空格、逗号)可能影响边界判断,需按需调整。 - 性能方面,正则方案的时间复杂度更优(O(M*K),K为单个字符串长度),适合数据量较大的场景;基础遍历实现更直观,适合小规模数据。
内容的提问来源于stack exchange,提问作者Matze._
相关产品推荐
相关产品推荐

