Reputation: 768
I am looking for the best way to check if a string contains a substring from a list of keywords.
For example, I create a list like this:
List<String> keywords = new ArrayList<>();
keywords.add("mary");
keywords.add("lamb");
String s1 = "mary is a good girl";
String s2 = "she likes travelling";
String s1 has "mary" from the keywords, but string s2 does not have it. So, I would like to define a method:
boolean containsAKeyword(String str, List<String> keywords)
Where containsAKeyword(s1, keywords)
would return true but containsAKeyword(s2, keywords)
would return false. I can return true even if there is a single substring match.
I know I can just iterate over the keywords list and call str.contains() on each item in the list, but I was wondering if there is a better way to iterate over the complete list (avoid O(n) complexity) or if Java provides any built-in methods for this.
Upvotes: 19
Views: 41515
Reputation: 157
Now you can use Java 8 stream for this purpose:
keywords.stream().anyMatch(keyword -> str.contains(keyword));
Upvotes: 9
Reputation: 16690
I would recommend iterating over the entire list. Thankfully, you can use an enhanced for loop:
for(String listItem : myArrayList){
if(myString.contains(listItem)){
// do something.
}
}
EDIT To the best of my knowledge, you have to iterate the list somehow. Think about it, how will you know which elements are contained in the list without going through it?
EDIT 2
The only way I can see the iteration running quickly is to do the above. The way this is designed, it will break early once you've found a match, without searching any further. You can put your return false statement at the end of looping, because if you have checked the entire list without finding a match, clearly there is none. Here is some more detailed code:
public boolean containsAKeyword(String myString, List<String> keywords){
for(String keyword : keywords){
if(myString.contains(keyword)){
return true;
}
}
return false; // Never found match.
}
EDIT 3
If you're using Kotlin, you can do this with the any
method:
val containsKeyword = myArrayList.any { it.contains("keyword") }
Upvotes: 14
Reputation: 830
In JDK8 you can do this like:
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
Upvotes: 5
Reputation: 1
Depending on the size of the list, I would suggest using the matches() method of String. String.matches takes a regex argument that, with smaller lists, you could sinply build a regular expression and evaluate it:
String Str = new String("This is a test string");
System.out.println(Str.matches("(.*)test(.*)"));
This should print out "true."
Or you could use java.util.regex.Pattern
.
Upvotes: 0
Reputation: 5235
Iterate over the keyword list and return true
if the string contains your keyword. Return false
otherwise.
public boolean containsAKeyword(String str, List<String> keywords){
for(String k : keywords){
if(str.contains(k))
return true;
}
return false;
}
Upvotes: 2
Reputation: 2642
Here is the solution
List<String> keywords = new ArrayList<>();
keywords.add("mary");
keywords.add("lamb");
String s1 = "mary is a good girl";
String s2 = "she likes travelling";
// The function
boolean check(String str, List<String> keywords)
Iterator<String> it = keywords.iterator();
while(it.hasNext()){
if(str.contains(it.next()))
return true;
}
return false;
}
Upvotes: 2
Reputation: 494
You can add all the words in keywords in a hashmap. Then you can use str.contains for string 1 and string 2 to check if keywords are available.
Upvotes: 0