我有TreeSet<String>
包含一些关键字。我需要测试一些String
以查看它们是否包含任何这些关键字。
我目前有:
String tweet = object.getText();
for (String keyword : keywords_set)
{
if(tweet.contains(keyword))
{
return true;
}
}
对于字符串流,是否有更优雅高效的方法?
答案 0 :(得分:2)
您将不会获得比JDK类和方法更高效的方法。您需要浏览String
中的每个Set
,然后检查您的String
是否包含它。
但是,如果您愿意使用第三方库Guava,则可以使其更清洁。
使用Guava,您可以使用Iterables.any(Iterable, Predicate)
如果iterable中的任何元素满足谓词,则返回true。
像这样使用
Set<String> keywords_set = ...
final String tweet = ...
return Iterables.any(keywords_set, new Predicate<String>() {
@Override
public boolean apply(String input) {
return tweet.contains(input);
}
});
借助Java 8,由于lambda expressions和aggregate operations,它会更加清晰。
答案 1 :(得分:1)
Aho-Corasick多字符串匹配算法: https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm
答案 2 :(得分:0)
以下是如何使用AhoCorasick的明确示例。
Robert Bor的java Aho-Corasick实现的I created a branch添加了一个“匹配”方法,一旦找到第一个匹配就返回true。
构建搜索trie非常重要。我已经包含了一个与您提供的代码示例匹配的无效方法实现。但是你真的想要在大量搜索中分摊trie构建的成本。要做到这一点,你真的想要改变调用你所包含的例子的代码。
我提供了一个如何构建搜索trie的示例,并将它们用于多次搜索。
public boolean doesTweetMatchSlow(String tweet, Set<String> keywords_set)
{
Trie searchTrie = new Trie();
for (String keyword : keywords_set) {
searchTrie.addKeyword(keyword);
}
return searchTrie.matches(tweet);
}
public Collection<String> findMatchingTweetsFaster(Iterable<String> tweets, Set<String> keywords_set)
{
List<String> matching = null;
if (tweets != null) {
matching = new ArrayList<>();
if (keywords_set != null && !keywords_set.isEmpty()) {
// build trie once.
Trie searchTrie = new Trie();
for (String keyword : keywords_set) {
searchTrie.addKeyword(keyword);
}
for (String tweet : tweets) {
// Re-use trie for every tweet.
if (searchTrie.matches(tweet)) {
matching.add(tweet);
}
}
}
}
return matching;
}