检查String是否包含Set <string> </string>中的关键字的优雅方法

时间:2014-03-15 21:03:36

标签: java string search treeset

我有TreeSet<String>包含一些关键字。我需要测试一些String以查看它们是否包含任何这些关键字。

我目前有:

String tweet = object.getText();
for (String keyword : keywords_set)
{
    if(tweet.contains(keyword))
    {
        return true;
    }
}

对于字符串流,是否有更优雅高效的方法?

3 个答案:

答案 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 expressionsaggregate operations,它会更加清晰。

答案 1 :(得分:1)

答案 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;
}