【问题标题】:How to improve search functionality in java?如何改进java中的搜索功能?
【发布时间】:2016-01-20 01:36:30
【问题描述】:

我做了一个简单的搜索功能,在大量 html 文件中查找字符串 (+8000) 这是我的代码:

public Boolean loadAssetTextAsString(Context context, String search,String name) {
    Boolean exist=false;
    BufferedReader in = null;
    try {
        StringBuilder buf = new StringBuilder();

        InputStream is = context.getAssets().open(name);

        in = new BufferedReader(new InputStreamReader(is));

        String str;
        boolean isFirst = true;
        while ( (str = in.readLine()) != null ) {
            if (isFirst)
                isFirst = false;
            else

            if (str.toLowerCase(Locale.getDefault()).contains(search)){

                Log.e(" SUCC",str);
                exist=true;
                break;
            } else {                    Log.e(" Fail",":(");
            }
        }
        return exist;
    } catch (IOException e) {
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
            }
        }
    }

    return exist ;
}

问题:
问题是这种方法非常慢而且根本没用。
有没有办法或算法在短时间内搜索大量文件?

【问题讨论】:

  • 你想要一个倒排索引而不是线性搜索(就像一本书后面的那个)。您可能不想自己实现它,这就是 Lucene(Java 搜索库)的用途。

标签: java android html database search


【解决方案1】:

我可以推荐的东西有很多;

首先,如果搜索到的字符串比 java 的原生 contains 函数太大,可能会很慢,因为这不是它的设计目的。 Native contains 函数将其操作委托给 indexOf 函数,对于大数据来说并不是特别快。根据您的硬件/时间要求,您可以寻找更高效的字符串搜索库。这是我使用的一个库,可以http://johannburkard.de/software/stringsearch/。它的使用非常简单,性能也相当不错。但我相信还有更好的选择。

您还可以使用 redix trie 或后缀树,它们更适合此类操作并且速度更快,但它们需要对数据进行预处理,并且可能需要更多的处理能力。

您没有说明是否使用线程,但据我了解,此搜索操作可以同时完成。即使您使用两个线程,您也可以将时间减少一半,提供读取操作不是瓶颈。

为了优化阅读操作,您可以做几件事。您可以使用新的 java.nio 包,它提供了一些漂亮的技巧。 java.io 包读取函数将文件完全读取到内存中,如果文件很大,这会很快耗尽内存。但是使用 java.nio 包,您可以更有效地执行此操作。

此外,您可以在搜索先前读取的字符串时进行读取操作并缓存结果以使用它们。

您也可以将 apache lucene 集成到您的代码中,但是它的学习曲线有些陡峭,但是这种搜索操作是构建 apache lucene 的原因。

【讨论】:

  • 非常感谢您写得很好:)。我会试试看
【解决方案2】:

您要查找的内容称为“全文索引”。 您可能会查看 Lucene(或位于其上方的 SOLR)。 我也听说一些数据库有类似的功能(例如 oracle),但我不确定它有多成熟。

基本上,全文索引的想法是预先准备。将每个文档分解成单词(Lucene 有一些可配置的分析器,这不是一项简单的任务),然后索引工具会为每个单词创建一个索引,说明哪些页面包含它。粗略地说:

Given the documents:
doc #1:  "I like cakes"
doc #2:  "My cake recipe"

You'll have an index:
"cake" -> pages 1, 2
"like"-> page 1
"recipe" -> page 2
...

【讨论】:

    猜你喜欢
    • 2013-03-14
    • 2014-09-10
    • 1970-01-01
    • 2019-08-04
    • 2020-12-25
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多