Saturday, June 02, 2007

How to override the equals method in Java

Well the other day i was reading about how to override the equals method in java . Here is brief summary of what i learnt .

Never Assume Anything:
First things first if you are writing a class whose equals method u have not overridden assumi ng that the equals method would never be called . never assume anything and atleast throw a UnsupportedOperationException to prevent others from doing a equality check on the instance of your class.

In terms of Code the equals method in your class should look like ,


public boolean equals(Object other){
throw new UnsupportedOperationException();
}
Contract of Equals Method:
The equals method must be
  • reflexive
  • transitive
  • symmetric
  • comapring with a null object should be false
So say if we want to compare two Point Objects


public class Point {
private Object x;

public Point( Object x ) {
this.x = x;
}

public boolean equals(Object point){
if(point == this)
return true;
if(!point instanceof Point)
return false;
Point other = (Point) point;
boolean result = true;
result = result && (x == other.x || (x != null && x.equals(other.x)));
return result;
}
}


Now ok i ve implemented a hypothetical Point class that has only 1 member entity called x . That entity is an Object rather than being a primitive type.

if(point == this)
return true;

In this line i check the references are equals , if they are then can we can skip other checking cause basically they are the same two references .

if(!point instanceof Point)
return false;

Second we make sure the object that we are comparing against is of the same type and is not null . The not null is implicit in the behaviour of instanceof operator . The instanceof operator makes sure that object on the left is not null othwerise it returns false.

Point other = (Point) point;

Next we perform the casting to the type of this object so that we can check each and every field .

boolean result = true;
result = result && (x != null && x.equals(other.x));

Next since x is the field being used here , we check if x is not null and if its not null we see if its equal to the x field in the other Object.

return result;

Finally we return the result

Dividing a Sequence into K ranges

Problem Statement:
Say you have a sequence of N numbers and you want to partition the sequence into K groups such that after applying a cost function c(i) for each group the sum of all cost functions over all groups is minimized or maximized?

Approach:
To divide the sequence into ranges , we will use K keys . The key used to divide the group can be indices or values . If its values then numbers in the
sequence can be used along with values in the sequence to partition values into groups whose key is K.

One way to do this is to use K-for loops , if the key is value based then probable something like this would work:


for i = 1 to n
for j = 1 to n
for k = 1 to n
for l = 1 to n{
key1 = seq[i]
key2 = seq[j]
key3 = seq[k]
key4 = seq[l]

}


After dividing the sequence into keys, use the keys to apply and aggregate the result of individual cost functions . Depending upon the requirement reduce the cost functions using functions like min , max depending upon if you want to minimize or maximize your result.

There you go , now u have 1 simple way of dividing a sequence into groups