lacas
lacas

Reputation: 14066

Android java custom sorting using Comparable

  @Override
      public int compareTo(final myRow another) {

        final int BEFORE    =-1;
        final int EQUAL     = 0;
        final int AFTER     = 1;

        if (this==another) return EQUAL;

        if (sorttype==sort_type.SORT_ABC) {

            int rv      =0;
            int sorted  =row.toLowerCase().compareTo(another.getRow().toLowerCase());

            if (this.getUserType()==user_type.USER_TYPE_BANNED) rv=AFTER;
            if (this.getUserType()==user_type.USER_TYPE_NORMAL) rv=sorted;
            if (this.getUserType()==user_type.USER_TYPE_FRIEND) rv=BEFORE;

            Log.e("sorted", row+" "+this.getUserType()+" - "+rv+" ");

            return rv;

        } else if (sorttype==sort_type.SORT_LOGINTIME) {

            if (this.getUserType()==user_type.USER_TYPE_BANNED) {
                return AFTER;
            }
            if (this.getUserType()==user_type.USER_TYPE_NORMAL) return EQUAL;
            if (this.getUserType()==user_type.USER_TYPE_FRIEND) {
                //int sorted    =row.toLowerCase().compareTo(another.getRow().toLowerCase());
                return BEFORE;
            }

            //return 0;
        }

        return 0;

        //return row.toLowerCase().compareTo(another.getRow().toLowerCase());
      }

I have a String userlist, with nick names. I have banned users, normal users, and friend users.

I d like to sort my friend users to the top of the list, and the banned users to the bottom of the list, and I d like to showing them is ASC style.

How can i do that?

So the structure is:

Abc  (friend)
abrt (friend)
dfgh (friend)

abdfg (normal user)
bnmm  (normal user)
wert  (normal user)

Andgh  (banned user)
Dfghhj (banned user)
Qwer   (banned user)

I get this:

06-19 14:43:46.586: ERROR/AndroidRuntime(23434): java.lang.IllegalArgumentException: Comparison method violates its general contract!

Upvotes: 3

Views: 8797

Answers (3)

lacas
lacas

Reputation: 14066

my code now :

  public enum user_type {USER_TYPE_FRIEND(1), USER_TYPE_NORMAL(2), USER_TYPE_BANNED(3);
      private final int order;
      user_type(int order) {
          this.order = order;
      }
      public int getOrder() {
          return this.order;
      }
  }

...

  @Override
  public int compareTo(final myRow another) {

    if (sorttype==sort_type.SORT_ABC) {
        if (this.getUserType().equals(another.getUserType())) {
            return this.getRow().toLowerCase().compareTo(another.getRow().toLowerCase());
        } else {
            return this.getUserType().compareTo(another.getUserType());
        }
    } 
    else {
        //LOGINTIME
        return this.getUserType().compareTo(another.getUserType());
    }
  }

Thanks, Sanjay!

Upvotes: 0

Sanjay T. Sharma
Sanjay T. Sharma

Reputation: 23218

Your code looks a bit complex. The simplest way would be to start from the highest priority field and move down to other fields. An example code would be:

public class Member implements Comparable<Member> {

    static enum Status {
        NORMAL(1), FRIEND(2), BANNED(3);

        private final int order;

        Status(int order) {
            this.order = order;
        }

        public int getOrder() {
            return this.order;
        }

    };

    private final String name;

    private final Status status;

    public Member(final String name, final Status status) {
        this.name = name;
        this.status = status;
    }

    @Override
    public int compareTo(Member o) {
        if (this.status.equals(o.status)) {
            return this.name.compareTo(o.name);
        } else {
            return this.status.compareTo(o.status);
        }
    }

    @Override
    public String toString() {
        return "Member [name=" + name + ", status=" + status + "]";
    }

    public static void main(String[] args) throws Throwable {
        Member[] members = {
                        new Member("abrt", Status.FRIEND),
                        new Member("dfgh", Status.FRIEND),
                        new Member("abdf", Status.NORMAL),
                        new Member("wert", Status.NORMAL),
                        new Member("andgh", Status.BANNED),
                        new Member("qwer", Status.BANNED)
        };
        List<Member> lst = Arrays.asList(members);
        Collections.sort(lst);
        System.out.println(lst);
    }


}

Upvotes: 5

Mat
Mat

Reputation: 206841

Your ABC sort logic doesn't work. If you pass in two USER_TYPE_FRIEND objects for instance, whatever their respective order, compareTo will always return BEFORE.

You need to implement this by first comparing the usertype.

If they are equal, you can return your row.compareTo(...) expression.

If not, you need to return before/after depending only on how those types "compare" in your logic (i.e. friend < normal < banned).

Upvotes: 1

Related Questions