2

I'd compare more than one only field of a object using the compareTo method. Is it possible?

for istance:

public int compareTo(Object o) {
    return field.compareTo(o.field);
}

I create this method to sort a collection. Obviously my object has to implement Comparable interface.

I'm guessing if is possible to compare not only one field in the same method compareTo.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
Mazzy
  • 13,354
  • 43
  • 126
  • 207
  • possible duplicate of [Best way to compare objects by multiple fields?](http://stackoverflow.com/questions/369512/best-way-to-compare-objects-by-multiple-fields) – blank Dec 13 '11 at 15:13

7 Answers7

3

Yes, it's possible. If the result of comparing the first field returns zero, then return the result of comparing the second field.

public int compareTo(SomeClass o) {
    int result = field1.compareTo(o.field1);
    if ( result == 0 ) {
        result = field2.compareTo(o.field2);
    }
    return result;
}

This gets cumbersome fairly quickly, which is why Guava provides a ComparisonChain. Example use:

public int compareTo(SomeClass o) {
    return ComparisonChain.start()
         .compare(field1, o.field1)
         .compare(field2, o.field2)
         .result();
}
Mark Peters
  • 80,126
  • 17
  • 159
  • 190
3

Yes, it's possible, for example like so:

public int compareTo(MyClass o){
  int ret = field1.compareTo(o.field1);
  if (ret != 0) return ret;
  ret = field2.compareTo(o.field2);
  if (ret != 0) return ret;
  ...
  return fieldN.compareTo(o.fieldN);
}
NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

You can certainly factor in other fields when comparing, but there's typically some order of precedence, just like sorting alphabetically only looks at the second letter if the first is the same:

public int compareTo(Object o){

   int comparison = field.compareTo(o.field);
   if (comparison != 0)
      return comparison;
   comparison = field2.compareTo(o.field2);
   if (comparison != 0)
      return comparison;
   //etc...
}
Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
0
public int compareTo(Object o){
  int res = field.compareTo(o.field);
  if(res==0)
    res=field1.compareTo(o.field1);
  return res;
}

should work

Kris
  • 14,426
  • 7
  • 55
  • 65
reederz
  • 983
  • 1
  • 12
  • 29
0

sure you can. however you must define the rule of comparison .

e.g.

you have

objectA{a=1;b=2;c=3}
objectB{a=20;b=1;c=6}

in your compareTo(Object o) method, you could compare this.fields with o.fields. you can even compare this.a to o.c if you really need. point is you have to define the rule, in which case objectA < objectB. etc..

Kent
  • 189,393
  • 32
  • 233
  • 301
0

Sure. Here's a relatively concise way of doing it.

public int compareTo(MyClass other) {
    return
        a!=other.a ? Integer.compare(a, other.a) :
        b!=other.b ? Integer.compare(b, other.b) :
                     Integer.compare(c, other.c);
}

(Integer.compare is from Java SE 7, but the implementation isn't difficult. Assumes int fields a, b, c, but is essentially the same for any field types you can compare.)

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
-1

You can do it any of following ways:

public int compareTo(Object o)
{    
    return (field.compareTo(o.field)==1 && field2.compareTo(o.field2)==0)? 0 : 1; 
} 

OR

public int compareTo(Object o)
{
    // add various if-else blocks
    // OR
    // call a separate method    
}
Azodious
  • 13,752
  • 1
  • 36
  • 71