我有String title
和List<String> bannedSubstrings
。现在我想执行单行检查,如果title
没有bannedSubstrings
。
我的方法:
if(bannedSubstrings.stream().filter(bannedSubstring -> title.contains(bannedSubstring)).isEmpty()){
...
}
不幸的是,流没有isEmpty()
方法。那你怎么解决这个问题呢?有一线解决方案吗?
答案 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();
}
}