我的ActionBar中有一个SearchView,在用户输入字符时显示建议。 我的建议存储在String ArrayList中,如下所示:
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 :(得分: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名称(即子字符串树的深度)按顺序排列。