Need a way to get to get the pattern in a string matched with List.stream().anyMatch()

Viewed 92

I'm matching a list of strings against a list of keywords. The goal is to get a string only one time if it has any of the keywords in it.

Actually I'm doing it with this loop:

for (int i = 0; i < keywords.size(); i++) {
   if (text.toLowerCase().contains(keywords.get(i))) {
      System.out.println("keyword >>> " + keywords.get(i)
         + " text >>> " + text);
      break;
   }
}

I like to know if there is a way to get the keyword if I'm using the java stream API like so:

if (keywords.stream().anyMatch(text.toLowerCase()::contains)) {
   System.out.println("keyword >>> " + "how to get the keyword here"
         + " text >>> " + text);
}
3 Answers

anyMatch returns a boolean

Using .filter() & findFirst() you can retrieve a value. Note that if you use findFirst() you get an Optional<String> and could either use ifPresent() like this:

keywords.stream()
    .filter(keyword -> text.toLowerCase().contains(keyword))
    .findFirst()
    .ifPresent(keyWord -> System.out.println("[2] keyword >>> " + keyWord + " text >>> " + text));

Or with Optional.isPresent() & Optional.get():

Optional<String> firstKey = keywords.stream()
    .filter(keyword -> text.toLowerCase().contains(keyword))
    .findFirst();

if (firstKey.isPresent()) {
    System.out.println("[2] keyword >>> " + firstKey.get() + " | text >>> " + text);
}

As a less fancy alternative to stream there is a nicer for syntax in Java 1.6+

for(String keyword: keywords) {
    if (text.toLowerCase().contains(keyword)) {
        System.out.println("keyword >>> " + keyword
                + "text >>> " + text);
        break;
    }
}

I find the for syntax easier to read than the stream syntax. In a previous job I did a lot of C++ lambda functions with BOOST and the code was hard to parse, and the errors hard to trace.

Another option would be to print an informational message if the keyword was not found. This is easily done by moving the isPresent test inside the print statement.

List<String> keywords =
        Arrays.asList("now", "is", "the", "time");
String text = "what are your names?";
        
Optional<String> opt = keywords.stream()
            .filter(keyword -> text
                    .toLowerCase().contains(keyword))
            .findFirst();


System.out.println(!opt.isPresent() ? "No keyword was found!" : 
                                "keyword >>> " + opt.get() 
                                        + " text >>> " + text);

Prints

No keyword was found!
Related