Thursday 1 August 2013

Top Most How to override hashcode in Java example - Tutorial

Equals and hashcode methods are two primary but yet one of most important methods for java developers to be aware of. Java intends to provide equals and hashcode for every class to test the equality and to provide a hash or digest based on content of class. Importance of hashcode increases when we use the object in different collection classes which works on hashing principle e.g. hashtable and hashmap. A well written hashcode method can improve performance drastically by distributing objects uniformly and avoiding collision. In this article we will see how to correctly override hashcode() method in java with a simple example. We will also examine important aspect of hashcode contracts in java. This is in continuation of my earlier post on overriding equals method in Java, if you haven’t read already I would suggest go through it.

General Contracts for hashCode() in Java

1) If two objects are equal by equals() method then there hashcode returned by hashCode() method must be same.

2) Whenever hashCode() mehtod is invoked on the same object more than once within single execution of application, hashCode() must return same integer provided no information or fields used in equals and hashcode is modified. This integer is not required to be same during multiple execution of application though.

3) If two objects are not equals by equals() method it is not require that there hashcode must be different. Though it’s always good practice to return different hashCode for unequal object. Different hashCode for distinct object can improve performance of hashmap or hashtable by reducing collision.

To better understand concept of equals and hashcode and what happens if you don’t override them properly I would recommend understanding of How HashMap works in Java

Overriding hashCode method in Java

Override java hashcode exampleWe will follow step by step approach for overriding hashCode method. This will enable us to understand the concept and process better.



1) Take a prime hash e.g. 5, 7, 17 or 31 (prime number as hash, results in distinct hashcode for distinct object)
2) Take another prime as multiplier different than hash is good.
3) Compute hashcode for each member and add them into final hash. Repeat this for all members which participated in equals.
4) Return hash

  Here is an example of hashCode() method

   @Override
    public int hashCode() {
        int hash = 5;
        hash = 89  hash + (this.name != null ? this.name.hashCode() : 0);
        hash = 89  hash + (int) (this.id ^ (this.id >>> 32));
        hash = 89  hash + this.age;
        return hash;
    }

It’s always good to check null before calling hashCode() method on members or fields to avoid NullPointerException, if member is null than return zero. Different data types has different way to compute hashCode.Integer members are simplest we just add there value into hash, for other numeric data-type are converted into int and then added into hash. Joshua bloach has full tables on this. I mostly relied on IDE for this.


Better way to override equals and hashCode

hashcode in Java exampleIn my opinion better way to override both equals and hashcode method should be left to IDE. I have seen Netbeans and Eclipse and found that both has excellent support of generating code for equals and hashcode and there implementations seems to follow all best practice and requirement e.g. null check , instanceof check etc and also frees you to remember how to compute hashcode for different data-types.


Let’s see how we can override hashcode method in Netbeans and Eclipse.

In Netbeans
1) Write your Class.
2) Right click + insert code + Generate equals() and hashCode().

How to override java hashcode
In Eclipse
1) Write your Class.
2) Go to Source Menu + Generate hashCode() and equals()


Things to remember while overriding hashcode in Java


1. Whenever you override equals method, hashcode should be overridden to be in compliant of equals hashcode contract.
2. hashCode() is declared in Object class and return type of hashcode method is int and not long.
3. For immutable object you can cache the hashcode once generated for improved performance.
4. Test your hashcode method for equals hashcode compliance.
5. If you don't override hashCode() method properly your Object may not function correctly on hash based collection e.g. HashMap, Hashtable or HashSet.



Complete example of equals and hashCode


public class Stock {
       private String symbol;
       private String exchange;
       private long lotSize;
       private int tickSize;
       private boolean isRestricted;
       private Date settlementDate;
       private BigDecimal price;
      
      
       @Override
       public int hashCode() {
              final int prime = 31;
              int result = 1;
              result = prime * result
                           + ((exchange == null) ? 0 : exchange.hashCode());
              result = prime * result + (isRestricted ? 1231 : 1237);
              result = prime * result + (int) (lotSize ^ (lotSize >>> 32));
              result = prime * result + ((price == null) ? 0 : price.hashCode());
              result = prime * result
                           + ((settlementDate == null) ? 0 : settlementDate.hashCode());
              result = prime * result + ((symbol == null) ? 0 : symbol.hashCode());
              result = prime * result + tickSize;
              return result;
       }
       @Override
       public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || this.getClass() != obj.getClass()){
                     return false;
              }
              Stock other = (Stock) obj;
             
return  
this.tickSize == other.tickSize && this.lotSize == other.lotSize && 
this.isRestricted == other.isRestricted &&
(this.symbol == other.symbol|| (this.symbol != null && this.symbol.equals(other.symbol)))&& 
(this.exchange == other.exchange|| (this.exchange != null && this.exchange.equals(other.exchange))) &&
(this.settlementDate == other.settlementDate|| (this.settlementDate != null && this.settlementDate.equals(other.settlementDate))) &&
(this.price == other.price|| (this.price != null && this.price.equals(other.price)));
                       
        
 }

}



Writing equals and hashcode using Apache Commons EqualsBuilder and HashCodeBuilder


EqualsBuilder and HashCodeBuilder from Apache commons are much better way to override equals and hashcode method, at least much better than ugly equals, hashcode generated by Eclipse. I have written same example by using HashCodebuilder and EqualsBuilder and now you can see how clear and concise they are.

    @Override
    public boolean equals(Object obj){
        if (obj instanceof Stock) {
            Stock other = (Stock) obj;
            EqualsBuilder builder = new EqualsBuilder();
            builder.append(this.symbol, other.symbol);
            builder.append(this.exchange, other.exchange);
            builder.append(this.lotSize, other.lotSize);
            builder.append(this.tickSize, other.tickSize);
            builder.append(this.isRestricted, other.isRestricted);
            builder.append(this.settlementDate, other.settlementDate);
            builder.append(this.price, other.price);
            return builder.isEquals();
        }
        return false;
    }
  
    @Override
    public int hashCode(){
        HashCodeBuilder builder = new HashCodeBuilder();
        builder.append(symbol);
        builder.append(exchange);
        builder.append(lotSize);
        builder.append(tickSize);
        builder.append(isRestricted);
        builder.append(settlementDate);
        builder.append(price);
        return builder.toHashCode();
    }
  
    public static void main(String args[]){
        Stock sony = new Stock("6758.T", "Tkyo Stock Exchange", 1000, 10, false, new Date(), BigDecimal.valueOf(2200));
        Stock sony2 = new Stock("6758.T", "Tokyo Stock Exchange", 1000, 10, false, new Date(), BigDecimal.valueOf(2200));

        System.out.println("Equals result: " + sony.equals(sony2));
        System.out.println("HashCode result: " + (sony.hashCode()== sony2.hashCode()));
    }

Only thing to concern is that it adds dependency on apache commons jar, most people use it but if you are not using than you need to include it for writing equals and hashcode method.

Related Java tutorials

LinkWithin

Related Posts Plugin for WordPress, Blogger...

Labels

Core Java programming core java interview question Core Java Faq's Servlets coding database jsp-servlet spring Java linux unix interview questions java investment bank Web Services Interview investment bank mysql Senior java developer interviews best practices java collection tutorial RMI SQL Eclipse FIX protocol tutorial tibco J2EE groovy java questions SCJP grails java 5 tutorial jdbc beginner error and exception Design Patterns Java Programming Tutorials fundamentals general object oriented programming xml Java Programs Hibernate Examples Flex JAMon Java xml tutorial logging Jsp Struts 2.0 Sybase and SQL Server debugging java interviews performance FIX Protocol interview questions JUnit testing WebSphere date and time tutorial experienced java IO tutorial java concurrency thread Ejb Freshers Papers IT Management Java Exapmle Java Script SQL and database tutorial examples Scwcd ant tutorials concurrency example and tutorial future state homework java changes java threading tricky Agile Business of IT Development JSTL Java JSON tutorial Java multithreading Tutorials PM Scrum data structure and algorithm java puzzles java tips testing tips windows 8 5 way to create Singleton Object Architect Interview Questions and Answers Architecture Architecure Bluetooth server as swing application that searches bluetooth device in 10 meter circle and show all devices. You can send file to any bluetooth device. C Programming CIO Callable Statement in Java Circular dependency of Objects in Java Comparable Example in Collection Custom annotation in Java Developer Interview Divide and rule example in java Drupal Example of Singleton Pattern FIX protocol ForkJoin Example in Java 7 Get data from dynamic table with Java Script Git HTML and JavaScript Health Hello World TCP Client Server Networking Program Hibernate Basics Hibernate Interview Question Answer J2EE Interview Question And Answers J2ME GUI Program JEE Interview QA JMS interview question Java J2EE Hibernate Spring Struts Interview Question Java System Property Java Threads Manager Portlets Provident Fund Read data from any file in same location and give the required result. Reading Properties File in Java Redpoint Rest WebService Client Rest Webservice Test SAL join with ven diagram SCP UNIX COMMAND SSL Singleton Pattern in Java Spring Bean Initialization methods and their order Spring Interview Questions Struts Struts 2.0 Basics Struts 2.0 Design Pattern Submit Html Form With Java Script On The Fly Unix executable For Java Program XOM DOM SAX XP books computers core java; core java; object oriented programming data structure; java investment bank; design pattern dtd duplicate rows in table get browser name with jquery grails podcast inner class java beginners tutorial java cache java networking tutorial java spring java util; java collections; java questions java.java1.5 linked list mailto function with all browser oracle database oracle duplicate rows orm schema social spring mvc questions struts transaction tricks tweet windows xslt