Android: поиск из большого массива

У меня есть набор записей около 29 000 записей. Мой экран содержит EditText Box для критериев поиска и Listview, содержащих все 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 динамически.

Я бы настаивал на использовании библиотеки Lambdaj, которая в основном используется в таких случаях, когда вы хотите ограничить циклы для сортировки и фильтрации коллекций.

Вот небольшой пример использования lambdaj для фильтрации ArrayList .

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

Это вернет полный фильтрованный ArrayList с помощью которого вы хотите заполнить ListView .

Вы также можете filter пользовательские классы – Java: что является лучшим способом фильтрации коллекции?

ОБНОВИТЬ:

Выше решение было case-sensitive к case-sensitive поэтому для работы вы можете добавить несколько совпадений .

Таким образом вы можете добавить 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 наименьшее из источника lambdaj и интегрировать в свой источник.

Вы можете использовать HashSet или LinkedHashSet (сохраняет порядок вставки) для быстрого поиска. С методом contains () этих классов.

Я бы предположил, что вы передали aCityStateTemp вам Adapter как ArrayList при инициализации Adapter

Теперь после изменения содержимого aCityStateTemp вам просто нужно вызвать adapter.notifyDataSetChanged() . Вам не нужно устанавливать aCityStateTemp в качестве нового ArrayList .

Вы можете хранить все данные в базе данных sqlite и извлекать искомый элемент, используя такой же запрос.