Android: search from a large array

I have a recordset of about 29,000 records. My screen contains an EditText window for search criteria and a list containing all 29,000 entries.

When searching on the specified path, it takes time and not output the stream less than I need.

My EditText contains

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(); } }); } 

The BindList () method sets the arraylist aCityStateTemp adapter. Any other way to find and create a new ArrayList dynamically.

+4
source share
4 answers

I would insist on using the Lambdaj Library, which is mainly used in cases where you want to limit the loops for sorting and filtering the Collection.

Here is a small example of using lambdaj to filter an ArrayList .

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

This will return the full filtered ArrayList with which you want to populate your ListView .

You can also filter Custom Classes - Java: what is the best way to filter a collection?

UPDATE:

The above solution was case-sensitive , so for work you can add some matches .

Here you can add Multiple Matchers ,

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

UPDATE:

Better yet, use filter(Matcher<?> matcher, T...array)

Here is how you can do it,

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

Also, if you are interested in using some lambdaj methods / functions, you can extract the source and make it work. I add the same for filter()

You can simply download hamcrest-all-1.0.jar(63 kb) and add the code below to get filter() working

 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; } } 

So, you can simply determine the smallest of the lambdaj sources and integrate into your source.

+13
source

You can use a HashSet or LinkedHashSet (preserves the insertion order) for a quick search. With the contains () method of these classes.

+2
source

I would suggest that you pass aCityStateTemp you Adapter as an ArrayList when initializing the Adapter

Now, after changing the contents of aCityStateTemp , you just need to call adapter.notifyDataSetChanged() . you do not need to install the aCityStateTemp adapter as a new ArrayList .

+1
source

You can store all the data in the sqlite database and retrieve the searched item using the same query.

0
source

Source: https://habr.com/ru/post/925002/


All Articles