搜索字符串数组以查找子字符串的最有效方法

3

假设我有一个字符串数组:

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

我想在数组每个索引中搜索一个特定的子字符串,比如 plain,然后返回第一个子字符串实例时返回true
最有效的方法是什么?
我知道我可以在循环中使用简单的break,但我听说使用 break 在 for 循环中是不好的做法。我还听说使用 whiledo-while 也不好。
我的实现方式
这是我的简单实现方式,使用了break
for (String[] index : tmpList) {
    retVal = index[2].toLowerCase().contains(keyword);

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

说明:

  • tmpList是一个ArrayList<String[]>
  • keyword是我正在尝试查找的内容

我会使用 indexOf(..) - MrSmith42
我认为在使用break时没有任何“坏处”。 - MrSmith42
1
这些话总的来说相当愚蠢。只需用一个循环,找到子字符串后就退出循环即可。例如,使用String.contains()函数来查找子字符串。 - Florent Guillaume
1
为什么使用break会被认为是一种不好的编程习惯呢?这就像说强制退出循环是一种不好的习惯。我可以找到成千上万个有用的情况来使用它。 - Jack
1
如果您先将赋值操作赋给 retval,然后再进行测试,我会感觉更好。 - Robert Harvey
显示剩余5条评论
2个回答

6
我知道可以在for循环中使用简单的break,但我听说人们说在for循环中使用break是不好的做法。
你在哪里找到这个信息的?那完全是错误的。在for循环中使用break是一种不好的做法吗? 只需使用for循环并遍历字符串。使用String#contains检查字符串是否具有特定子字符串。然后将字符串存储在变量中(或者需要它的索引),并使用break;

1
我曾经从一位教授那里听说过,但现在我不确定她是在谈论 break 还是 goto。无论如何,感谢提供 SO 链接。 - FilmiHero
专业人士建议在学习编程时不要使用break和goto,因为他们希望你更多地思考算法而不是实现。goto应该尽量少用,因为它会使你的代码难以阅读。 - unziberla

0

我知道apache-commons有一个叫做StringUtils的实用类,可以为您提供优雅的解决方案。

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

我不喜欢的一件事是它只会在第一个找到的实例中返回true。我不完全确定你试图做什么,但如果你不关心数组中不匹配模式的索引,我建议使用称为filter的高阶函数。

Guava、lambdaJ和Apache-Commons是支持函数式编程的库。

以下是一些在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);

这个方法的作用是从列表中删除不符合模式的任何字符串。如您所见,声明一个Predicate对象有点冗长。如果您使用Apache-Commons或Guava,它看起来会很相似,但这就是lambdaJ的用处。

Predicate只是一个术语,表示接受单个参数并返回布尔值的函数,您可能已经在Matcher类中使用过它们。Hamcrest拥有一些最好的Matcher库可用,因此lambdaJ只是在其周围构建了一个函数编程库。它易于使用且高度可读。


只是一件小事:您在行末缺少一个括号,应该是if(StringUtils.contains(content, pattern)){}。顺便说一句,回答很棒。 - Enkk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接