1

Hello there i need to sort my array list that contains the following kind of data:

 name1 1111 1622 122ks
 name3 1211 4122 1aks
 name2 1113 1322 12sks
 name10 2111 1222 12dks
 ...
 name4 asd1 2334 asd8

There is simple Model class to populate date! Now What i Want to do is to compare on the bases of the name i.e name1 compare to name2 and so on. For this I am doing like:

  public class ABC implements Comparator<MyModel> {
    @Override
    public int compare(MyModel o1, MyModel o2) {
    return o1.name.compareTo(o2.name);
   }
 }    

It give me the output as I required! But when there are name more than 10 i Mean names after 10 11 12 my comparator wont gives me the required sorted list as i need, and the output becomes:

    name1 1111 1622 122ks
    name10 1211 4122 1aks
    name11 1113 1322 12sks
    name12 2111 1222 12dks
    ...
    name2 asd1 2334 asd8
    ... (sorted so on)

What i been doing wrong? Is the way I am doing is wrong or there is some other way to achieve it! Thanks in advance!

Android Nerd
  • 21
  • 1
  • 4
  • This sorting occurs because the space character is considered lower in sort order than other characters such as numbers. Also, each character is compared individually, not aggregated into numbers. If you want to sort with the numbers being handled as you expect, you will need to write your own comparator. – Jason Jun 14 '17 at 22:53

2 Answers2

4

It's because those numbers (1, 10, 2) are treating as String. so you will get these order name1 name10 name2

what you want is called Natural sorting please look at

Natural sort order string comparison in Java - is one built in?

Java String Number Comparator

Sample: https://repl.it/ImA2/1

Yichz
  • 9,250
  • 10
  • 54
  • 92
1

If name is constant, you can use substring in your comparator to compare numbers after that. For example:

public class ABC implements Comparator<MyModel> {
    @Override
    public int compare(MyModel o1, MyModel o2) {
    return Integer.parseInt(o1.name.substring(4))-Integer.parseInt(o2.name.substring(4));
   }
 }

EDIT:

If name isn't constant, you can loop through the name first to find the first digit and save the index to substring from that index

Mohd
  • 5,523
  • 7
  • 19
  • 30