Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if an ArrayList of Strings contains substrings of another ArrayList of Strings?

List<String> actualList = Arrays.asList ("mother has chocolate", "father has dog");
List<String> expectedList = Arrays.asList ("mother", "father", "son", "daughter");

Is there a way to check if expectedList contains any substrings of the strings in actualList?

I found a nested for-each solution:

public static boolean hasAny(List<String> actualList, List<String> expectedList) {
    for (String expected: expectedList)
        for (String actual: actualList)
            if (actual.contains(expected))
                return true;

    return false;
}

I was trying to a find lambda solution, but I could not. All the methods I found check for String#equals and not for String#contains.

It would be nice to have something like:

CollectionsUtils.containsAny(actualList, exptectedList);

But it compares strings using String#equals not String#contains.

EDIT:

Based on questions: I want to get TRUE if ALL subStrings from actualList are part of expectedList. And solution from Kevin below works for me.

like image 373
Nikola Jakubiak Avatar asked Sep 27 '18 12:09

Nikola Jakubiak


People also ask

How do you check if an ArrayList contains another ArrayList?

ArrayList contains() method in Java is used for checking if the specified element exists in the given list or not. Returns: It returns true if the specified element is found in the list else it returns false.

How do you check if ArrayList contains part of a string?

To check if ArrayList contains a specific object or element, use ArrayList. contains() method. You can call contains() method on the ArrayList, with the element passed as argument to the method. contains() method returns true if the object is present in the list, else the method returns false.

How do you check if a string matches any string in a list Java?

Using Java 8 The idea is to call the anyMatch() method on the stream elements, which return true if and only if any element matches with the supplied predicate. To check for a substring, you can use the contains() method.

How do you check if a string exists in an ArrayList Java?

contains() method can be used to check if an element exists in an ArrayList or not. This method has a single parameter i.e. the element whose presence in the ArrayList is tested. Also it returns true if the element is present in the ArrayList and false if the element is not present.

How to check if a string contains any of the substrings?

This post will discuss how to check if a string contains any of the substrings from a List. 1. Using String.contains () method The idea is to iterate over the entire list using an enhanced for loop and call the String.contains () method for each substring.

How to check if element is present in ArrayList of strings?

Since, the element is present in the HashSet, contains () method should return true. In this example, we will define a ArrayList of Strings and add some elements to it. The we shall check if element "f" is present in this ArrayList using contains () method. Since, the element is not present in the ArrayList, contains () method should return false.

What is ArrayList contains () method in Java?

ArrayList contains() method in Java is used for checking if the specified element exists in the given list or not. Syntax: public boolean contains(Object) object-element to be searched for

How to check if a list contains a string in Python?

list#contains () compares the whole string in the list rather than part of string instead you can do i.e. iterating over the list and checking contains on elements of list. You could use something like if (string.indexOf (" (f)")!=-1) fnum++. This would look like this in your code.


2 Answers

How about something like this:

list1.stream().allMatch(s1 -> list2.stream().anyMatch(s2 -> s1.contains(s2)))

Try it online.

  • allMatch will check if everything is true
  • anyMatch will check if at least one is true

Here something similar in Java 7 style without lambdas and streams to understand a bit better what is going on:

boolean allMatch = true;       // Start allMatch at true
for(String s1 : list1){
  boolean anyMatch = false;    // Start anyMatch at false inside the loop
  for(String s2 : list2){
    anyMatch = s1.contains(s2);// If any contains is true, anyMatch becomes true as well
    if(anyMatch)               // And stop the inner loop as soon as we've found a match
      break;
  }
  allMatch = anyMatch;         // If any anyMatch is false, allMatch becomes false as well
  if(!allMatch)                // And stop the outer loop as soon as we've found a mismatch
    break;
}
return allMatch;

Try it online.


If you prefer to have a CollectionsUtils.containsAny(list1, list2) you can reuse elsewhere in your code, you could always make one yourself:

public final class CollectionsUtil{
  public static boolean containsAny(ArrayList<String> list1, ArrayList<String> list2){
    return list1.stream().allMatch(s1 -> list2.stream().anyMatch(s2 -> s1.contains(s2)));
    // Or the contents of the Java 7 check-method above if you prefer it
  }

  private CollectionsUtil(){
    // Util class, so it's not initializable
  }
}

Which can then be used as you wanted:

boolean result = CollectionsUtils.containsAny(actualList, expectedList);

Try it online.

like image 120
Kevin Cruijssen Avatar answered Oct 22 '22 21:10

Kevin Cruijssen


I am 99% sure you are not looking for hasAny like the most upvoted answer here, but instead you want to see if all from expectedList are contained in any String in actualList. For that it would be beneficial to first create a Set and work of that (since contains is O(1) for HashSet and opposed to O(n) for List).

Think about it now, since all you want is contains, you can split that actualList and create unique words from that:

private static boolean test(List<String> actualList, List<String> expectedList) {

    Pattern p = Pattern.compile("\\s+");

    Set<String> set = actualList.stream()
            .flatMap(p::splitAsStream)
            .collect(Collectors.toSet());

    return expectedList.stream().allMatch(set::contains);

}
like image 28
Eugene Avatar answered Oct 22 '22 21:10

Eugene