2

I wanted to sort the list based on two properties but on certain conditions. The below class has two properties - memberid,membernumber. And the values are as below.

obj ()
{
   memberid;
   membernumber;
}

Values Assigned : 
obj1 = {1,15}
obj2 = {3,10}
obj3 = {2,20}
obj4 = {2,10}
obj5 = {3,15}
obj6 = {4,25}
obj7 = {2,50}

We need the sorting as:

First sort it based on memberId, and if member Id are same sort it based on membernumber highest membernumber should come first. so the output should be :

obj1 = {1,15}
obj7 = {2,50} >> As 2 are multiple sort on membernumber as highest being 50
obj3 = {2,20}
obj4 = {2,10}
obj5 = {3,15}
obj2 = {3,10}
obj6 = {4,25}

I am able to sort it based on MemberId using collections.sort, But am not sure how to have that equal condition and sort it based on MemberNumber.

Any help is appreciated.

Sorting class which I am using in Collections.sort().

public class sortId implements Comparator<obj > {

public int compare(obj o1, obj o2)
   {
     int id1 =  o1.getmemberId();
     int id2 =  o2.getmemberId();       
     return id1 - id2 ;     
    }
}
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
Hero
  • 639
  • 4
  • 12
  • 33
  • override the collection.sort method – Rahul Singh May 03 '17 at 17:56
  • 1
    I'm not sure this is a duplicate, or if you actually are looking for the compare function that you need, but anyway - take a look here: https://stackoverflow.com/questions/2839137/how-to-use-comparator-in-java-to-sort – MByD May 03 '17 at 17:56
  • @MByD - That is normal Comparator implementation. I will add the comparator class which I have written in my question which is similar . Its only on memberId not sure how to write the logic for membernumber, I want it to sort memberNumber only for the objects which has same memberIds. – Hero May 03 '17 at 18:04

4 Answers4

2

You can use Collections.sort, and to sort descending you can use the negative to inverse your sort like so :

List<obj> list = Arrays.asList(new obj(1, 15), new obj(3, 10), new obj(2, 20),
        new obj(2, 10), new obj(3, 25), new obj(2, 50));

Collections.sort(list, new Comparator<obj>() {
    @Override
    public int compare(obj o1, obj o2) {
        if (o1.getMemberid() != o2.getMemberid()) {
            return o1.getMemberid() - o2.getMemberid();
        } else {
            //for the second sort you can use negative to sort descending
            return -(o1.getMembernumber() - o2.getMembernumber());
            //     ^-------------------------------------------------------
        }
    }
});

Outputs

[{1,15}, {2,50}, {2,20}, {2,10}, {3,25}, {3,10}]
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
1

you can use Comparator interface for custom sorting and override compare method with nested logic.

BHAR4T
  • 338
  • 3
  • 14
  • I have added my normal Comparator implementation which I have written in the above question which is similar . Its only on memberId not sure how to write the logic for membernumber, I want it to sort memberNumber only for the objects which has same memberIds. – Hero May 03 '17 at 18:08
  • ` public int compare(obj o1, obj o2) { if(e1.getmemberId() > e2.getmemberId()){ return 1; } else if (e1.getmemberId() < e2.getmemberId()){ return -1; }else if(e1.getmemberId() == e2.getmemberId()){ if(e1.getmemberNo() > e2.getmemberNo()){ return 1; } else{ return -1; } } }` – BHAR4T May 03 '17 at 18:17
1

You can use the static methods from Comparator for this, with then thenComparing been taken into account after comparing. E.g. if your list is objs and have the appropriate getters:

objs.sort(comparingInt(Obj::getMemberid)
    .thenComparing(comparingInt(Obj::getMembernumber).reversed()));

Or

objs.sort(comparingInt(Obj::getMemberid)
    .thenComparing(Obj::getMembernumber, reverseOrder()));

Note how .reversed() or reverseOrder() are used to sort in descending order for membernumber but default ascending for memberid.

Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
0

You code is halfway there. What you miss is the case where the first check is equal, so you should implement something like that:

public int compare(obj o1, obj o2)
{
    int id1 =  o1.getmemberId();
    int id2 =  o2.getmemberId();
    if (id1 == id2) {
         // check other condition, return result
    }
    else {
        return id1 - id2;
    }
}

As a side note: follow naming conventions, and name your classes in CamelCase (Obj instead of obj)

MByD
  • 135,866
  • 28
  • 264
  • 277
  • Yeah , I just wrote that in the question the class has different name and properties . Thanks though – Hero May 03 '17 at 18:21