How to compare Objects in Java

compare1

Today I would like to demonstrate how to compare objects in java, especialy the non-String java Objects.

The Object

Suppose we have a Box object, which is just a square kube. Just like this:

compare1

The code of the Box class is as follows:

class Box {
    int height;
    int width;

    public Box(int h, int w) {
        this.height = h;
        this.width = w;
    }
    
    public int getArea() { //compute the area of the box
        return height*width;
    }
}

If you compare them directly like this:

Box box1 = new Box(5,3); // area is 15
Box box2 = new Box(3,5); // area is 15

System.out.println(box1==box2); //result would be false, because java compare their memory addresses internally.

System.out.println(box1>box2); // would not compile successfully, because java do NOT allow this operation, the '> <' can ONLY be used with numbers. 

So, how to do the comparison job with custom objects?

Make it Comparable

To compare objects , you must implement the java.lang.Comparable interface in java, just like this:

class Box implements Comparable<Box> { //add interface implementation
    int height;
    int width;

    public Box(int h, int w) {
        this.height = h;
        this.width = w;
    }

    @Override
    public int compareTo(Box o) { // Compare this object to another box, and return an integer
                                  // return positive if this box is larger than the other
                                  // return negative if this box is smaller than the other
                                  // return 0 if they are equal.
        return getArea()-o.getArea();
    }

    public int getArea() {
        return height*width;
    }
}

Compare them!

Now you can compare the Boxes like this:

Box box1 = new Box(2,3); // area is 6
Box box2 = new Box(3,5); // area is 15

int result= box1.compareTo(box2); // call the compareTo method to compare box1 and box2

if(result>0) {
    System.out.println("box1 bigger than box2");
}else if(result==0) {
    System.out.println("box1 equals with box2");
}else {
    System.out.println("box1 smaller than box2"); // should print this line
}

Run it, we get this:

box1 smaller than box2

Compare in a Collection

If you put the box in a list , then you can call Collections.sort to compare them automatically. Just like this:

List<Box> boxes = new ArrayList<>();
boxes.add(new Box(5,2)); // area is 10
boxes.add(new Box(3,1)); // area is 3
boxes.add(new Box(3,2)); // area is 6

Collections.sort(boxes); // compare them automatically
                         // java would call the compareTo method of Box

for(Box box:boxes) {
    System.out.println(box.getArea());
} // should print 3,6,10

Run the above code, we get this:

3 
6 
10

Use the commons-lang3 library

You should leverage the toolbox from commons-lang3, There is a new tool named ComparableUtils which you can use to compare objects easily and inline.

Import the library:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.10</version>
</dependency>

Then use it to compare objects:

import org.apache.commons.lang3.compare.ComparableUtils;

System.out.println(
   ComparableUtils.is(new Box(2,2)).lessThan(new Box(3,3))); //should print true
System.out.println(
   ComparableUtils.is(new Box(3,4)).greaterThan(new Box(3,3)));//should print true

Run the code, we get this:

true
true

There are many useful methods in commons-lang’s ComparableUtils:

  • between

    Checks if [b <= a <= c] or [b >= a >= c] where the a is the tested object.

  • betweenExclusive

    Checks if [b < a < c] or [b >a > c] where the a is the tested object.

  • ge

    Checks if the tested object is greater than or equal to b

  • gt

    Checks if the tested object is greater than b

  • le

    Checks if the tested object is less than or equal to b

  • lt

    Checks if the tested object is less than b

References