Monday, April 30, 2018

Comparing objects in Java

This is our example class:
public class Person {
 private final int age;
 private final String name;
 public Person(int age, String name) {
  this.age = age;
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public String getName() {
  return name;
 }
}
When implementing this.compareTo(that) or compare(this, that) follow these rules:
  • return -1 if this is less than that
  • return 0 if this equals to that, also should give the same result as Object.equals()
  • return 1 if this is greater than that
The two basic ways to achieve comparison are the followings:

Implementing the Comparable interface

public class Person implements Comparable<Person> {
 // ...
 @Override
 public int compareTo(Person that) {
  if (this.getName().compareTo(that.getName()) == 0) {
   if (this.getAge() < that.getAge()) return -1;
   else if (this.getAge() > that.getAge()) return 1;
   else return 0;
  }
  else return this.getName().compareTo(that.getName());
 }
 // ...
}

Using a Comparator

The Comparator interface can be implemented by an anonymous class in the class or at the place of usage like when giving it to Collections.sort() as an argument.
If only the compare() method is implemented that's enough.
public class Person {
 // ...
 public static Comparator<Person> byAge() {
  return new Comparator<Person>() {
   @Override
   public int compare(Person p1, Person p2) {
    if (p1.getAge() < p2.getAge()) return -1;
    else if (p1.getAge() > p2.getAge()) return 1;
    else return p1.getName().compareTo(p2.getName());
   }
  };
 }

 public static Comparator<Person> byName() {
  return new Comparator<Person>() {
   @Override
   public int compare(Person p1, Person p2) {
    if (p1.getName().equals(p2.getName())) {
     if (p1.getAge() < p2.getAge()) return -1;
     else if (p1.getAge() > p2.getAge()) return 1;
     else return 0;
    }
    else return p1.getName().compareTo(p2.getName());
   }
  };
 }
 // ...
}

Sorting Objects

Now that we have ways to compare the object, we can use that for sorting:
private Person a = new Person(20, "Amanda");
private Person b = new Person(20, "Anna");
private Person c = new Person(21, "Anna");
private Person d = new Person(19, "Beata");
private List<Person> list = Arrays.asList(b, a, d, c);

// using the Comparable implementation
Collections.sort(list);
assertEquals(Arrays.asList(a, b, c, d), list);
Collections.reverse(list);
assertEquals(Arrays.asList(d, c, b, a), list);
Collections.sort(list, Collections.reverseOrder());
assertEquals(Arrays.asList(d, c, b, a), list);

// using the Comparator implementation
Collections.sort(list, Person.byAge());
assertEquals(Arrays.asList(d, a, b, c), list);
Collections.sort(list, Collections.reverseOrder(Person.byAge()));
assertEquals(Arrays.asList(c, b, a, d), list);
Further readings:

1 comment:

  1. Nice explanation and examples on comparing objects in java. Thanks for sharing.

    Cheers,
    http://www.flowerbrackets.com/string-compare-java-program/

    ReplyDelete