4

I have a recordset of about 29,000 records. My Screen contains EditText Box for Search Criteria and Listview containing all 29,000 records.

By searching with the listed way it takes time and not giving flow less output as 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();
            }
        });
    }

BindList() method is setting the arraylist aCityStateTemp to adapter. Any Other way to Search and Create new ArrayList dynamically.

Moog
  • 10,193
  • 2
  • 40
  • 66
Vishal Khakhkhar
  • 2,106
  • 3
  • 29
  • 60

4 Answers4

14

I would insist to use Lambdaj Library which is mostly used in such cases where you want to restrict loops for sorting and filtering Collections.

Here is a small example for using lambdaj for filtering ArrayList.

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

This will return a complete 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:

Above solution was case-sensitive so to work around you can add Multiple Matchers.

Like this you can add Multiple Matchers,

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

UPDATE:

Even better way is to use filter(Matcher<?> matcher, T...array)

Here is how you can do that,

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

Also, if you are interested in using some of the methods/features of lambdaj, you can extract the source and get it working. I am adding the same for filter()

You can just download hamcrest-all-1.0.jar(63 kb) and add below code to get the 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 just sort out the least from lambdaj source and integrate in your source.

Community
  • 1
  • 1
Lalit Poptani
  • 67,150
  • 23
  • 161
  • 242
  • 1
    Superb library +1 Mr Poptani. – Mohammed Azharuddin Shaikh Sep 10 '12 at 09:28
  • A very good library but sadly it doesn't work with Android. I saw the following link before I gave up. Despite that, I'll keep it as an option for non-Android projects if I ever need to. http://stackoverflow.com/a/16528057/1276636 – Sufian Jan 29 '14 at 10:09
  • What is Matchers for this library ? I found error in Matchers function.Please explain it – Anand Savjani Sep 29 '15 at 04:59
  • public static List filter(Matcher> matcher, Iterable iterable) { if (iterable == null) return new LinkedList(); else{ List collected = new LinkedList(); Iterator iterator = iterable.iterator(); if (iterator == null) return collected; while (iterator.hasNext()) { T item = iterator.next(); if (matcher.matches(item)) collected.add(item); } return collected; } } – Mohammad Rajob Mar 14 '16 at 13:07
  • ArrayList sortedArrayList = (ArrayList) filter(Matchers.anyOf( Matchers.containsString(searchText),Matchers.containsString(searchText.toUpperCase())), productList); – Mohammad Rajob Mar 14 '16 at 13:08
  • Please check my two comments, the size of new list is always zero. – Mohammad Rajob Mar 14 '16 at 13:09
  • @MohammadRajob prefer asking a seperate question with your source code – Lalit Poptani Mar 14 '16 at 13:11
  • @LalitPoptani Please help http://stackoverflow.com/questions/35988831/android-arraylist-filter-with-hamcrest-jar – Mohammad Rajob Mar 14 '16 at 13:26
2

You can use HashSet or LinkedHashSet(keeps insertion order) for fast searching. With contains() method of that classes.

narek.gevorgyan
  • 4,165
  • 5
  • 32
  • 52
1

I would assume that you have passed aCityStateTemp to you Adapter as ArrayList while initializing the Adapter

Now after changing the contents of aCityStateTemp, you just need to call adapter.notifyDataSetChanged(). you don't need to set the aCityStateTemp to adapter as new ArrayList.

Adil Soomro
  • 37,609
  • 9
  • 103
  • 153
  • Adil.. I wasnot doing as the way you suggested but now I have tried with changing the way you suggested. infact adapter.notifyDataSetChanged() is a good way to refresh the adapter so have did it. but taking the same time. – Vishal Khakhkhar May 01 '12 at 05:26
0

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

Manikandan
  • 1,479
  • 6
  • 48
  • 89