Comparing objects
Primitive data types have values stored directly, while objects are a reference to the location where instance variables are stored.
For example,
1
int x = 10;
1
char ch = '$';
1
boolean flag = true;
On the other hand, objects hold a reference to the location where the instance variables are stored.
For example, consider the class Rectangle
:
1
2
3
4
5
6
7
8
9
10
11
12
class Rectangle {
public double width, height;
public Rectangle(double w, double h) {
width = w;
height = h;
}
public double area() {
return width * height;
}
}
Let the client code be:
1
2
3
4
5
public class Client {
public static void main(String[] args) {
Rectangle a4 = new Rectangle(8.27, 11.69);
}
}
Here, object a4
holds a reference to a block of memory where instance variables width
and height
are stored.
Comparing variables vs. comparing objects
Comparing variables
When you compare two variables of primitive data type, you are comparing their contents.
1
2
3
4
5
6
7
8
9
int x = 5;
int y = 5;
if(x == y) { //evaluates to true
System.out.println("Same"); //is displayed, as expected
}
else {
System.out.println("Different");
}
Comparing objects
If we compare objects like this, what we are checking is if they refer to the same instance!
Let the client code be:
1
2
3
4
5
6
7
8
9
10
11
12
public class Client {
public static void main(String[] args) {
Rectangle r1 = new Rectangle(1.2, 2.5);
Rectangle r2 = new Rectangle(1.2, 2.5);
if(r1 == r2) { //evaluates to false
System.out.println("Same");
}
else { //is executed!
System.out.println("Different"); //is displayed!
}
}
}
The above code would end up in displaying Different
as r1
and r2
do not refer to the same instance.
Therefore, we cannot use the primitive comparison operator ==
.
We define (technically, we over-ride) the instance methodcompareTo()
. We call it on an object and pass the object to which we are comparing it as the parameter.
Typically, we’d compare objects of the same class but we can also compare any comparable objects. For example, we can compare a rectangle with a circle (based on area) or a person with a tree (based on age).
Comparison has three possible outcomes:
- Calling object is greater than the parameter object: in this case,
compareTo
returns 1. - Calling object is lesser than the parameter object: in this case,
compareTo
returns -1. - Calling object is equal to the parameter object: in this case,
compareTo
returns 0.
Let’s take an example of implementing compareTo
for Rectangle
class, where comparison is based on the area.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public int compareTo(Rectangle other) {
double callingObjectArea = this.area();
double parameterObjectArea = other.area();
if(callingObjectArea > parameterObjectArea)
return 1;
/*
control comes here only if
callingObjectArea <= parameterObjectArea
*/
if(callingObjectArea < parameterObjectArea)
return -1;
/*
control comes here only if
callingObjectArea == parameterObjectArea
*/
return 0;
}
Consider the following example of calling the compareTo
method:
1
2
3
4
5
6
7
public class Client {
public static void main(String[] args) {
Rectangle r1 = new Rectangle(1.2, 3.5); //area is 4.2
Rectangle r2 = new Rectangle(1.4, 2.5); //area is 3.5
int status = r1.compareTo(r2);
}
}
The following events take place upon the execution of r1.compareTo(r2)
:
this
refers to the same instance as the calling object (r1
).other
refers to the same instance as the parameter object (r2
).- Control is transferred to method call.
Define the
compareTo
method in theCircle
class such that it returns 1 if the calling object is larger than the parameter, -1 if it’s smaller, and 0 if it’s the same size.SOLUTION
1 2 3 4 5 6 7 8 9 public int compareTo(Circle other) { if(this.radius > other.radius) { return 1; } if(this.radius < other.radius) { return -1; } return 0; }
In a separate client, compare two
Circle
objectsc1
andc2
and store the result in variablecomp
.SOLUTION
1 2 3 4 5 6 public class Client { public static void main(String[] args) { //assuming c1 and c2 are objects of class Circle int comp = c1.compareTo(c2); } }