Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check if a string has a substring from a List?

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.

like image 605
swap310 Avatar asked Nov 24 '14 17:11

swap310


3 Answers

Now you can use Java 8 stream for this purpose:

keywords.stream().anyMatch(keyword -> str.contains(keyword));
like image 171
Rutu Trivedi Avatar answered Sep 22 '22 14:09

Rutu Trivedi


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") }
like image 13
AdamMc331 Avatar answered Oct 08 '22 11:10

AdamMc331


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
like image 5
fdam Avatar answered Oct 08 '22 12:10

fdam