1

I have fragment with ListView connected to custom ArrayAdapter. Also on this fragment I have TextView for to sort items by name. Currently it works in next style, when I input any text in this TextView I'm changing sorting order for SQL request, like so: On first positions I'm showing items which contain "entered text" and after that all other items.

Now I'm doing it from my view, by stupid way, I'm every time reselect data from database, with ordering by some specific order field, which = 1 if Name field contain "entered text" and = 0 if not contain.

Can somebody tell me if it's possible to sort ArrayList in this style without reselect data from database?

Here is my solution:

    if (mActualFilter.equals("")) {
      Collections.sort(mProductItems, new Comparator<ProductItem>() {
        @Override
        public int compare(ProductItem o1, ProductItem o2) {
          return o1.getName().compareToIgnoreCase(o2.getName());
        }
      });
    } else {
      Collections.sort(mProductItems, new Comparator<ProductItem>() {
        @Override
        public int compare(ProductItem o1, ProductItem o2) {
          String mName1 = o1.getName();
          String mName2 = o2.getName();

        if ((mName1.toLowerCase().contains(mActualFilter.toLowerCase())) && (!mName2.toLowerCase().contains(mActualFilter.toLowerCase()))) {
          return -1;
        } else if  ((!mName1.toLowerCase().contains(mActualFilter.toLowerCase())) && (mName2.toLowerCase().contains(mActualFilter.toLowerCase()))) {
            return 1;
          } else {
            return 0;
          }
        }
      });
    }
Yevhen
  • 791
  • 9
  • 24
  • Possible duplicate of [How to sort an ArrayList in Java](http://stackoverflow.com/questions/18441846/how-to-sort-an-arraylist-in-java) – Devrim Mar 08 '17 at 13:51
  • Is there a big overhead in re-querying the database? It seems that you will add unnecessary complexity - what happens if the underlying data changes after you've sorted your ArrayList, you'll have to re-query and then re-sort the data for the ArrayList. – Mark Mar 08 '17 at 13:55
  • No it's not big overhead, it's question only from my feeling side, maybe we have more elegant way. If not i will leave it like now. My data is not changing till i close this fragment – Yevhen Mar 08 '17 at 14:02

1 Answers1

1

Does the data change according to user's input?

If it changes, then you have no option but to re-select data.

If it doesn't change, you can sort the Array using java.util.Collections.sort(array, comparator) (and you can create custom comparators that sort based on the fields you need)

Example (supposing I have a class with 2 fields):

class MyClass {
    private String someField;
    private int otherField;
    // getters and setters, etc..
}

I can create a comparator that compares someField:

Comparator<MyClass> someFieldComparator = new Comparator<MyClass>() {
    @Override
    public int compare(MyClass m1, MyClass m2) {
        return m1.getSomeField().compareTo(m2.getSomeField());
    }
};

Method compare must return -1 if m1 is "less than" m2 (which means, if m1 must be before m2 when I sort), 1 if m1 is "greater than" m2 (m1 must be after m2 when I sort), or 0 if they are considered "equal" (it doesn't matter the order of m1 and m2 when I sort). In this case, I used compareTo of String class, because it does this same logic with strings. If I call Collections.sort(list, someFieldComparator), it will sort according to values of someField.

For otherField, I could create another comparator:

Comparator<MyClass> otherFieldComparator = new Comparator<MyClass>() {
    @Override
    public int compare(MyClass m1, MyClass m2) {
        int v1 = m1.getOtherField();
        int v2 = m2.getOtherField();
        if (v1 < v2) {
            return -1;
        }
        if (v1 > v2) {
            return 1;
        }
        return 0;
    }
};

Note that I used the same logic of returning -1, 1 or 0 as described above.

So you can create as many comparators as needed and use them accordingly.

  • No data is not changing. Can you please provide example how to do it for my situation. All what i found is next: Collections.sort(mProductItems, new Comparator() { @Override public int compare(ProductItem o1, ProductItem o2) { return 0; } }); But here as you can see i can compare 2 items from my list and not each item with some free text – Yevhen Mar 08 '17 at 13:56
  • I included some code in the answer. But I also suggest taking a look at the documentation: https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html –  Mar 08 '17 at 14:12
  • Thank's for your help. It works. My code in first message – Yevhen Mar 08 '17 at 14:25
  • One more suggestion. Instead of `if (something == true)` you can just use `if (something)` and instead of `if (something == false)` you can use `if (!something)` - because when `something` is a boolean value there's no need to use `==` in `if` clauses –  Mar 08 '17 at 14:36