Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Saturday, August 10, 2013

Java - Overriding hashCode() and equals()

Java provides a convenient way to calculate 'deep comparison' of objects via hashCode() and equals() methods. Every object has the default implementation for these methods. Deep comparison of objects can be implemented by overriding hashCode() and equals() methods. Several rules are defined by Java creators which we go through in the following sections. You can access these rules from Javadocs of Object.

Rules to override hashCode()

  1. Invocations of hashCode() should return the same value when fields of object do not change
  2. If two objects are equal based on equals() method, both the objects should return the same hashCode()
  3. It is not required that the hashCode() be dissimilar when two objects are not equal based on equals()

Rules to override equals()

  1. Reflexive: An object should be equal to itself: a.equals(a) is true
  2. Symmetric: If an object is equal to another object based on equals(), then these objects should be equal irrespective of which object's equal method is called: => if a.equals(b) is true then b.equals(a) is also true 
  3. Transitive: if two objects are equal based on equals(), then these objects are equal to any other objects that are equal to any of these objects: if a.equals(b) is true and b.equals(c) is true, then a.equals(c) is true
  4. Consistent: multiple invocations of equals() on objects should return the same value, if the underlying values used to check equality are not modified
  5. Equality check with null is false 

Example: Consider the following class that contains an int and the way hashCode() and equals() are overridden.

    class A
    {
        int x;
        public int setX(int x);
        {
            this.x = x;
        }
        public int getX()
        {
            return this.x;
        }
        public int hashCode()
        {
            return x;
        }
        public int equals(Object object)
        {
            boolean isEqual = true;
            if(object == null)
            {
                isEqual = false;
            }
            else if(Class.forName(object) != this.class))
            {
                isEqual = false;
            }
            else
            { 
                A compareObject = (A) object;
                if(this.x != compareObject.x)
                {
                    isEqual = false;
                }
            }
            return isEqual;
        }
    }

Verify that the rules for hashCode() and equals() are satisfied: Example:

A a,b,c,d;
a.setX(5);
b.setX(5);
c.setX(5);
d.setX(6);

Rules for hashCode():
  1. a.hashCode() will always return 5
  2. a.equals(b) is true. also, a.hashCode() and b.hashCode() return 5
  3. a.equals(d) is false (5 != 6). though a.hashCode() can be same as d.hashCode(), in our implementation they are different

Rules for equals():
  1. a.equals(a) will always return true
  2. a.equals(b) is true and b.equals(a) is true
  3. a.equals(b) is true and b.equals(c) is true and c.equals(a) is also true
  4. a.equals(b) is true as long as the 'x' value of the objects is not changed
  5. a.equals(null) is false

Saturday, July 20, 2013

Java - New Line Separator


A string can be constructed to have new line as 
String string = "Hello" + "\n" + "World"; 

Output 

Hello
World

Instead of using "\n", a better way to get the new line is from the System class.
A new line separator is stored in the System class in a Properties object. 
The new line separator can be retrieved by the following line 

System.getProperty("line.separator");


Java - Exception Stack Trace

Stack traces are helpful when a Java application throws exception. When the Java application is running in a console, we see the trace in console window. In order to log the trace to a file, we have to capture the stack trace in such a way, so as to be able to print it with the structure in tact.  The following Java code snippet, converts a stack trace to String format that can be used to save it to a file.

public static String printStackTrace (Throwable throwable)
{
    final Writer writer = new StringWriter ();
    final PrintWriter printWriter = new PrintWriter (writer);
    throwable.printStackTrace (printWriter);
    return writer.ToString();
}