这是一些有效的代码,但看起来不够优雅。在另一个字符串中搜索这些字符串的更好方法是什么?
String AndyDaltonInjury = "broken right thumb";
if (AndyDaltonInjury.toLowerCase().contains("broken") &&
(AndyDaltonInjury.toLowerCase().contains("knee") ||
AndyDaltonInjury.toLowerCase().contains("leg") ||
AndyDaltonInjury.toLowerCase().contains("ankle") ||
AndyDaltonInjury.toLowerCase().contains("thumb") ||
AndyDaltonInjury.toLowerCase().contains("wrist")))
{
System.out.println("Marvin sends in the backup quarterback.");
}
使用Set
集合及其方法Set::contains
insde流分割数组与空格(" "
)分隔符:
Set<String> set = new HashSet<>(Arrays.asList("knee", "leg", "ankle", "thumb", "wrist"));
String lower = "broken right thumb".toLowerCase();
String split[] = lower.split(" ");
if (lower.contains("broken") && Arrays.stream(split).anyMatch(set::contains)) {
System.out.println("Marvin sends in the backup quarterback.");
}
此外,我强烈建议您使用较低的变量名称。
作为已经发布的基于Set的解决方案的替代方案(从可见性的角度来看,我发现它更好),这可以使用正则表达式来完成:
final Pattern brokeStuffPattern = Pattern.compile(
".*\\bbroken?\\b.*\\b(?:knee|leg|ankle|thumb|wrist)s?\\b.*"
+ "|.*\\b(?:knee|leg|ankle|thumb|wrist)s?\\b.*\\bbroken?\\b.*",
Pattern.CASE_INSENSITIVE
);
if (brokeStuffPattern.matcher(AndyDaltonInjury).matches()) {
...
}
这将解释复数和动词的完美时态,例如如果匹配“断腿”。
您可以创建缺少的函数(包含all / any)作为方法,或使用Lambda表示法表达它们:
BiPredicate<String, List<String>> containsAll = (text, words) ->
words.stream().allMatch(word -> text.toLowerCase().contains(word));
BiPredicate<String, List<String>> containsAny = (text, words) ->
words.stream().anyMatch(word -> text.toLowerCase().contains(word));
if (containsAll.test(AndyDaltonInjury, Arrays.asList("broken")) &&
containsAny.test(AndyDaltonInjury, Arrays.asList("knee", "leg", "ankle", "thumb", "wrist"))) {
System.out.println("Marvin sends in the backup quarterback.");
}
你可以试试这个:
String test = "broken right thumb";
Predicate << ? super String > machCriteria = s - > Stream.of("knee", "leg", "ankle", "thumb", "wrist").anyMatch(e - > e.equals(s.toLowerCase()));
String result = Pattern.compile(" ").splitAsStream(test).anyMatch(machCriteria) ? "Marvin sends in the backup quarterback." : "";
System.out.println(result);
如果您需要检查大量文本中的大量文本,基于哈希的算法可能会为您提供更好的性能。
HashSet
将是一个很好的第一次尝试,因为搜索(测试集合中包含的密钥)是否在O(1)和O(n)之间。
但是,我强烈建议考虑使用[Bloom Filter][1]
的好处。它可以很好地用作预滤器,因为它可以提供可预测的O(k)性能。由于过滤器的误报率很小,因此您还需要运行第二阶段。
查看Guava BloomFilter以获得良好的实施。
Bloom Filter的另一个好处是它不包含原始数据集,只是一个简化的哈希值,这意味着它的大小是最小的。这意味着它更适合分布式系统,因为它非常有效地复制。在像Apache Spark这样的环境中,您甚至可以将其设置为Broadcast变量,因为一旦生成它通常会在时间上保持不变。