一行检查String是否包含bannedSubstrings

时间:2015-05-12 09:37:25

标签: java string lambda java-8 java-stream

我有String titleList<String> bannedSubstrings。现在我想执行单行检查,如果title没有bannedSubstrings

我的方法:

if(bannedSubstrings.stream().filter(bannedSubstring -> title.contains(bannedSubstring)).isEmpty()){
    ...
}

不幸的是,流没有isEmpty()方法。那你怎么解决这个问题呢?有一线解决方案吗?

4 个答案:

答案 0 :(得分:8)

听起来你想要阅读anyMatch

if (bannedSubstrings.stream().anyMatch(title::contains)) {
    // bad words!
}

相反,还有noneMatch

if (bannedSubstrings.stream().noneMatch(title::contains)) {
    // no bad words :D
}

如果title是一个长字符串,这个效率不是很高(但我认为标题通常不应该很长)。

答案 1 :(得分:4)

如果你想要一个有效的解决方案并且你有很多bannedSubstrings,我想,将它们加入单个正则表达式会更快:

Pattern badWords = Pattern.compile(bannedSubstrings.stream().map(Pattern::quote)
    .collect(Collectors.joining("|")));

然后像这样使用它:

if (badWords.matcher(title).find()) {
   ...
}

这应该从子字符串构建前缀树,因此扫描速度会明显加快。如果您的情况不是表现问题,请使用其他答案。

答案 2 :(得分:3)

我想你正在寻找这样的东西:

if(bannedSubstrings.stream().anyMatch(title::contains)){

}

答案 3 :(得分:0)

你选择的答案非常好,但是对于真正的表现,你可能最好将坏词列表预先编译成正则表达式。

public class BannedWordChecker {
    public final Pattern bannedWords;

    public BannedWordChecker(Collection<String> bannedWords) {
        this.bannedWords =
            Pattern.compile(
                bannedWords.stream()
                    .map(Pattern::quote)
                    .collect(Collectors.joining("|")));
    }

    public boolean containsBannedWords(String string) {
        return bannedWords.matcher(string).find();
    }
}