Java 单行检查字符串是否包含横幅子字符串
我有一个Java 单行检查字符串是否包含横幅子字符串,java,string,lambda,java-8,java-stream,Java,String,Lambda,Java 8,Java Stream,我有一个字符串标题和一个列表横幅子字符串。现在,我想执行一行检查title是否没有那些横幅子字符串 我的做法: if(bannedSubstrings.stream().filter(bannedSubstring -> title.contains(bannedSubstring)).isEmpty()){ ... } 不幸的是,流没有isEmpty()方法。那么你将如何解决这个问题呢?是否有一种单线解决方案?听起来您想了解一下: 相反,还有: 如果title是一个长字符串(但
字符串标题
和一个列表横幅子字符串
。现在,我想执行一行检查title
是否没有那些横幅子字符串
我的做法:
if(bannedSubstrings.stream().filter(bannedSubstring -> title.contains(bannedSubstring)).isEmpty()){
...
}
不幸的是,流没有isEmpty()
方法。那么你将如何解决这个问题呢?是否有一种单线解决方案?听起来您想了解一下:
相反,还有:
如果title
是一个长字符串(但我想标题通常不应该很长)。我想您正在寻找这样的内容:
if(bannedSubstrings.stream().anyMatch(title::contains)){
}
Pattern badWords = Pattern.compile(bannedSubstrings.stream().map(Pattern::quote)
.collect(Collectors.joining("|")));
if (badWords.matcher(title).find()) {
...
}
如果您想要一个高效的解决方案,并且您有许多横幅子字符串
,我想,将它们合并到单个regexp中会更快,如下所示:
if(bannedSubstrings.stream().anyMatch(title::contains)){
}
Pattern badWords = Pattern.compile(bannedSubstrings.stream().map(Pattern::quote)
.collect(Collectors.joining("|")));
if (badWords.matcher(title).find()) {
...
}
然后像这样使用它:
if(bannedSubstrings.stream().anyMatch(title::contains)){
}
Pattern badWords = Pattern.compile(bannedSubstrings.stream().map(Pattern::quote)
.collect(Collectors.joining("|")));
if (badWords.matcher(title).find()) {
...
}
这将从子字符串中构建前缀树,因此扫描速度将显著加快。如果您的情况不关心性能,请使用其他答案。您选择的答案非常好,但要获得真正的性能,您可能最好将坏单词列表预先编译成正则表达式
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();
}
}
公共类BannedWordChecker{
公共最终模式横幅词;
公共横幅文字检查器(收集横幅文字){
这是我的名字=
Pattern.compile(
bannedWords.stream()
.map(模式::引号)
.collect(收集器.连接(“|”);
}
公共布尔值包含BannedWord(字符串){
返回bannedWords.matcher(string.find();
}
}
我认为最好在这里使用noneMatch
。@mkrakhin我想这取决于函数的总体布局,但这是一个很好的建议,我会将其添加到我的答案中。当然。我刚才提到了它,因为OP在他的if
:)中检查了空值,而且noneMatch
和anyMatch
不需要检查整个流,所以有必要保持bandensubstrings
排序,以降低在title
中出现的概率。或者,从横幅子串
长度的某个点开始,创建并行流
而不是流
@principal理想域是有意义的,regexp方法渐进地更好,因为不管你有多少个被禁止的单词,它应该最多需要一次通过title
的迭代,而我的建议是在最坏的情况下,每个被禁止的单词都需要一次通过title
的迭代(这是字符串正常的情况!)。长话短说,我仍然认为我上面的解决方案对于任何正常用例来说都是最好的,但是如果你有一个大的(固定的)禁词集和一个长标题,regexp方法是聪明的,而且性能相对更好。@nikis:这样做会额外发现所有在这种情况下不必要的坏词。@TagirValeev同意,这是我最初想到的第一个解决方案,已经发布了另一个解决方案。您在解决方案中假设BannedSubstring不包含对正则表达式具有特殊意义的字符。是的。即使不是这样,也可以很容易地修复。编辑。