Search code examples
androidandroid-listviewandroid-arrayadaptercompareto

string.compareTo(string) not yielding correct results on sort


I have a list view with place distances, as shown below:

100
200
300
400
500
50
600
70
40

i need to sort this place distances in both ascending and descending order. So wat i did was, sorting the adapter and use adapter.notifyDataSetChanged(). Everything works fine if the distances are 3 digit numbers ie., 230, 450, 352, 254 and so on. But if the place distance is 2 digit like 52, 65, 75 etc, i am getting wrong sorted values as shown below.

for ascending order : after sort i am getting this order

100
200
300
400
500
600
50
60
70

for descending order : after sort i am getting this order

70
60
50
600
500
400
300
200
100

my code for sorting is shown below:

case R.id.action_sort_dist_fn:

            adapter.sort(new Comparator<Place>() {

                @Override
                public int compare(Place lhs, Place rhs) {
                    return rhs.getPlaceDistance().compareTo(
                            lhs.getPlaceDistance());
                };
            });

            adapter.notifyDataSetChanged();
            break;

        case R.id.action_sort_dist_nf:

            adapter.sort(new Comparator<Place>() {

                @Override
                public int compare(Place lhs, Place rhs) {
                    return lhs.getPlaceDistance().compareTo(
                            rhs.getPlaceDistance());
                };
            });

Place.java

public class Place {
    String placeName = "";
            String placeDistance="";
            String placeCategoryIcon;

    public Place(String placeName, String placeDistance,
            String placeCategoryIcon) {

        this.placeName = placeName;
        this.placeDistance = placeDistance;
        this.placeCategoryIcon = placeCategoryIcon;
    }

    public String getPlaceName() {
        return placeName;
    }

    public void setPlaceName(String placeName) {
        this.placeName = placeName;
    }

    public String getPlaceDistance() {
        return placeDistance;
    }

    public void setPlaceDistance(String placeDistance) {
        this.placeDistance = placeDistance;
    }

    public String getPlaceCategoryIcon() {
        return placeCategoryIcon;
    }

    public void setPlaceCategoryIcon(String placeCategoryIcon) {
        this.placeCategoryIcon = placeCategoryIcon;
    }

}

Solution

  • First of all the sorting you give is not the actual one you are getting. E.g the second one is actually:

    70
    600
    60
    500
    50
    400
    300
    200
    100
    

    The comparison shouldn't be done using strings - it compares lexicographically, which means that the comparison is as described here. So "abc" is greater than "ab" and "d" is greater than "ccc".

    You want to compare the number values, so please do so. One option is to use Integer.valueOf to get the actual integer value equivalents of the values you use.

    By the way I see no gain for you to have placeDistance a String field. Why don't you have it as Integer all along?