2014-05-04 30 views
0

我的ActionBar中有一個SearchView,在用戶鍵入字符時顯示建議。 我的建議被存儲在一個字符串的ArrayList是這樣的:Android中的高效SearchView建議

private ArrayList<String> mSuggestions; 

然後我搜索功能顯示基於查詢的文本建議。

public boolean onQueryTextChange(String newText) { 
    mSuggestions.clear(); 
    for(MyObject o : mObjects) 
     if(o.getName().contains(newText)) 
      mSuggestions.add(o.getName()); 

    return false; 
} 

它具有爲O(n)效率,因爲它遍歷陣列搜索的查詢字。因此,當mSuggestions.size()增長時,它變得緩慢且不夠高效。

我想使用另一個比ArrayList更高效的容器來搜索O(log(n)),但沒有找到最合適的容器。

有人對此有任何建議嗎?

在此先感謝。

+0

爲了獲得真正高效的結果,您可以查看SQLite FTS3虛擬表,但這很複雜,需要花時間根據數據庫記錄的數量首次構建表。 Google for FTS3。我認爲Android開發網站也有一個如何使用它的例子。 – Squonk

+0

聽起來很有趣。我正在尋找的是更高層次的東西,比如使用另一個容器代替ArrayList或任何算法。感謝您的迴應。 – voghDev

回答

0

由於您正在進行子字符串搜索,因此您可以考慮使用HashMap將每個可能的子字符串映射到包含子字符串的對象列表(HashMap<String, List<MyObject>>)。這假定您的mObjects列表未針對每個查詢進行更新(例如,如果您正在執行基於查詢的加載結果的網絡請求),並且您可以預先計算保持靜態或多或少靜態的數據結構。然後你的查找將在O(1)中完成,但是你會花費空間效率來存儲所有的子串。你的代碼是這樣:

private Map<String, List<MyObject>> mObjectLookupMap = 
    new HashMap<String, List<MyObject>>(); 

// precompute lookup map with all possible substrings 

public boolean onQueryTextChange(String newText) { 
    mSuggestions.clear(); 

    if (mObjectLookupMap.containsKey(newText)) { 
     for (MyObject o : mObjectLookupMap.get(newText)) 
     mSuggestions.add(o.getName()); 
    } 

    return false; 
} 

更節省空間的解決辦法可能是使用Trie存儲子。然後,您的查找時間將按照最長的MyObject名稱(即子串樹的深度)排列。