简体   繁体   中英

Most efficient way to search String array for substring

Say I have an array of Strings like so:

0 ["Some plain text"]
1 ["Foobar chicken"]

I want to search each String (in each index of the array) for a particular substring, say plain , and then return true when the first instance of the substring is found.

What's the most effecient way to do this?

I know I can do a simple break in a for-loop but I've heard people say that using break in a for-loop is bad-practice. I also hear that using a while and do-while isn't good either.

My Implementation

Here's my simple implimentation using break:

for (String[] index : tmpList) {
    retVal = index[2].toLowerCase().contains(keyword);

    if (retVal) // Break when retVal is true
        break;
}

Where:

  • tmpList is an ArrayList<String[]>
  • keyword is what I'm trying to find

I know I can do a simple break in a for-loop but I've heard people say that using break in a for-loop is bad-practice.

Where did you find this? That is completely wrong. Is it a bad practice to use break in a for loop?

Just use a for loop and loop through the String s. Use String#contains to check to see if the String has a specific substring. Then store the String in a variable (or the index if you need it) and break; .

I know that apache-commons has a utility class called StringUtils that could give you a elegant solution.

public boolean foo(String[] array, String pattern){
    for(String content : array){
        if(StringUtils.contains(content, pattern){
            return true;
        }
    }
    return false;
}

One thing I don't like about this is that it will only return true at the first found instance. I'm not entirely sure what you are attempting to do but if you don't if don't care about indexes in the array that don't match the pattern, I would recommend using the higher order function called filter.

Guava, lambdaJ, and Apache-Commons, are libraries that have support for functional programming.

Below is some sudo-code that should work in Apache-Commons.

List<String> content = Arrays.asList(strArray);
Predicate matchesPattern = new Predicate("asdf"){{
    private String pattern;
    public Predicate(String pattern){
        this.pattern = pattern;
    }
    @Overload
    public boolean evaluate(Object input){

        if(input instanceOf String){
            StringUtils.contains((String)input, pattern
        }
        return false;
    }
}};

CollectionUtils.filter(content, matchesPattern);

What this does is remove any String from the list that doesn't matches the pattern. As you can see it's a little verbose declaring a Predicate object. If you use Apache-Commons or Guava it's going to look similar, but that's where lambdaJ comes to the rescue.

A predicate is just term for function that takes in a single argument and returns a boolean value, you probably already used them before with the Matcher class. Hamcrest has some of the best Matcher's library available, so lambdaJ just built a functional programming library around it. It's easy to use and highly readable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM