4

我有大约 29,000 条记录的记录集。我的屏幕包含用于搜索条件的 EditText 框和包含所有 29,000 条记录的列表视图。

通过使用列出的方式进行搜索,它需要时间并且不会根据我的需要提供更少的输出。

我的 EditText 包含

final EditText txtSearchCity = (EditText) findViewById(R.id.edtCity);
        txtSearchCity.addTextChangedListener(new TextWatcher() {
            @Override
            public void afterTextChanged(Editable s) {
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {
                aCountryIDTemp.clear();
                aCityStateTemp.clear();

                for (int i = 0; i < aCountryID.size(); i++) {
                    if (aCityState
                            .get(i)
                            .toLowerCase()
                            .contains(
                                    txtSearchCity.getText().toString()
                                            .toLowerCase())) {
                        aCountryIDTemp.add(aCountryID.get(i));
                        aCityStateTemp.add(aCityState.get(i));
                    }
                }

                BindList();
            }
        });
    }

BindList() 方法将 arraylist aCityStateTemp 设置为适配器。动态搜索和创建新 ArrayList 的任何其他方式。

4

4 回答 4

14

我会坚持使用Lambdaj 库,它主要用于您想要限制循环以对集合进行排序和过滤的情况。

这是一个使用 lambdaj 进行过滤的小例子ArrayList

ArrayList<String> sortedArrayList = select(arrList, having(on(String.class),
                                                   Matchers.containsString("a");

这将返回一个完整的过滤ArrayList器,您要使用它来填充您的ListView.

您还可以filter自定义类 - Java:过滤集合的最佳方法是什么?

更新:

上述解决方案case-sensitive可以解决您可以添加Multiple Matchers的问题。

像这样你可以添加Multiple Matchers

ArrayList<String> sortedArrayList = select(arrList, having(on(String.class),
   (Matchers.anyOf(Matchers.containsString("a"),Matchers.containsString("A")))));

更新:

更好的方法是使用filter(Matcher<?> matcher, T...array)

这是你可以做到的,

ArrayList<String> sortedArrayList = filter(Matchers.anyOf(
           Matchers.containsString("a"),Matchers.containsString("A")), arrList);

此外,如果您对使用 的某些方法/功能感兴趣lambdaj,您可以提取源代码并使其正常工作。我正在添加相同的filter()

您只需下载hamcrest-all-1.0.jar(63 kb)并添加以下代码即可filter()正常工作

public static <T> List<T> filter(Matcher<?> matcher, Iterable<T> iterable) {
    if (iterable == null)
        return new LinkedList<T>();
    else{
        List<T> collected = new LinkedList<T>();
        Iterator<T> iterator = iterable.iterator();
        if (iterator == null)
            return collected;
        while (iterator.hasNext()) {
            T item = iterator.next();
            if (matcher.matches(item))
                collected.add(item);
        }
        return collected;
    }
}

因此,您可以从lambdaj源代码中挑选出最少的内容并集成到您的源代码中。

于 2012-05-01T10:21:07.493 回答
2

您可以使用 HashSet 或 LinkedHashSet(保持插入顺序)进行快速搜索。使用该类的 contains() 方法。

于 2012-04-30T11:52:09.530 回答
1

我会假设你在初始化时已经传递给aCityStateTempAdapterArrayListAdapter

现在更改内容后aCityStateTemp,您只需要调用adapter.notifyDataSetChanged(). 您不需要将aCityStateTempto 适配器设置为 new ArrayList

于 2012-04-30T12:22:57.517 回答
0

您可以将所有数据存储在 sqlite 数据库中,并使用类似查询检索搜索到的项目。

于 2012-04-30T13:07:57.247 回答