如何检查字符串是否具有来自 List 的子字符串?

2022-09-03 05:36:05

我正在寻找检查字符串是否包含关键字列表中的子字符串的最佳方法。

例如,我创建了一个如下列表:

List<String> keywords = new ArrayList<>();
keywords.add("mary");
keywords.add("lamb");

String s1 = "mary is a good girl";
String s2 = "she likes travelling";

字符串 s1 具有关键字中的“mary”,但字符串 s2 没有它。所以,我想定义一个方法:

boolean containsAKeyword(String str, List<String> keywords)

其中将返回 true,但将返回 false。即使存在单个子字符串匹配项,我也可以返回 true。containsAKeyword(s1, keywords)containsAKeyword(s2, keywords)

我知道我可以只是迭代关键字列表,并在列表中的每个项目上调用str.contains(),但我想知道是否有更好的方法来迭代整个列表(避免O(n)复杂性),或者Java是否为此提供了任何内置方法。


答案 1

我建议迭代整个列表。值得庆幸的是,您可以使用增强的 for 循环:

for(String listItem : myArrayList){
   if(myString.contains(listItem)){
      // do something.
   }
}

编辑据我所知,您必须以某种方式迭代列表。想想看,如果不通过它,您将如何知道列表中包含哪些元素?

编辑 2

我能看到迭代快速运行的唯一方法是执行上述操作。按照这种设计方式,一旦你找到匹配项,它就会提前中断,而无需进一步搜索。您可以将返回 false 语句放在循环的末尾,因为如果您检查了整个列表而没有找到匹配项,则显然没有。下面是一些更详细的代码:

public boolean containsAKeyword(String myString, List<String> keywords){
   for(String keyword : keywords){
      if(myString.contains(keyword)){
         return true;
      }
   }
   return false; // Never found match.
}

编辑 3

如果您使用的是 Kotlin,则可以使用以下方法执行此操作:any

val containsKeyword = myArrayList.any { it.contains("keyword") }

答案 2

在 JDK8 中,您可以执行以下操作:

public static boolean hasKey(String key) {
   return keywords.stream().filter(k -> key.contains(k)).collect(Collectors.toList()).size() > 0;
}

hasKey(s1); // prints TRUE
hasKey(s2); // prints FALSE