Solved

Implementation of the hash code method

Posted on 2002-07-10
13
299 Views
Last Modified: 2013-11-23
Hello sir/madam,

  How do i implement the hashCode and equals() method on the class?Kindly elaborate...
  I am having  a problem in the implementation Class of the ManagedConnectionFactory of the J2EE connector architecture specifications..
Regards
Anuradha
0
Comment
Question by:anuchoudhry
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
13 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 7143151
The hashCode() method can be implemented quite simply by:

return super.hashCode();

As far as the equals() method is concerned, sincce I'm not familiar with this interface, I can't really help. But generally, what you need to do is decide what fields are important in the basic functionality. It is these fields that will distinguish one interface from another. You should compare these individually and make equals() method reflect this. The same fields, of course, would be important in supplying a toString() method, which you should also implement probably.
0
 
LVL 9

Expert Comment

by:doronb
ID: 7143315
0
 
LVL 9

Accepted Solution

by:
doronb earned 20 total points
ID: 7143320
Hi,


The hashCode() method must never be implemented by:

return super.hashCode();

because then you are simply calling hashCode on the class that your class inherits from; invocation of the inherited super.hashCode method would happen normally since the method is inherited so strictly invoking the

super method is not going to change anything and supply a better hashCode than the super class would have.

The 2nd thing to remember is that most object inherit their hashCode implementation from the java.lang.Object which simply returns the memory location of the java object in question. This simple implementation is

good enough if the state which the object is in when you're asking for the hashCode should NEVER determine the hashCode value itself!!!

Most objects that contain data relevant to the hashCode (for example, objects that are keys or ID's) should not allow the data to change once the hashCode has been calculated and used (to store the object as a key in

a HashMap for instance). Changing the data for the object would render the hashCode value incompatible with the data.

In some cases, objects can re-calculate their hashCode based on their current data but this scenario is too complicated to explain right now, so lets stick with objects that calculate their hashCode only once and do not

allow their data to change once the hashCode has been calculated.

The code in my next post shows how an object can hold data used when calculating the hashCode. Once the hashCode has been calculated, the data members can never be changed!! Since the hashCode is determined by the data members, the equals method is also added to verify that two instances are equal if they contain the same data in their data members.

continued --->
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 9

Expert Comment

by:doronb
ID: 7143323
The code:

package <your-package>;

import java.io.Serializable;

public class RemoteClientId implements Serializable {
     private String clientIpAddress;
     private long timeStampKey;
     private transient int hashCodeValue;

     public RemoteClientId() {
          clientIpAddress = null;
          timeStampKey = 0;
          hashCodeValue = 0;
     }

     public RemoteClientId(String ip, long timeStamp) {
          setClientIpAddress(ip);
          setTimeStampKey(timeStamp);
          hashCodeValue = calcHashCode();
     }

     private int calcHashCode() {
          int result = hashCodeValue;
          try {
               byte[] ba1 = clientIpAddress.getBytes();
               byte[] ba2 = Long.toBinaryString(timeStampKey).getBytes();
               int i;
               int k = 1;
               for (i = 0; i < ba1.length; i++) {
                    result += (int)ba1[i] * k;
                    k++;
               }
               for (i = 0; i < ba2.length; i++) {
                    result += (int)ba2[i] * k;
                    k++;
               }
          } catch (NullPointerException ex) {
               if (clientIpAddress != null) {
                    // This address is invalid so create an illegal hashCode..
                    result = -1;
               }
          } catch (Exception ex) {
               ex.printStackTrace();
          }
          return result;
     }

     public int hashCode() {
          if (hashCodeValue == 0) {
               hashCodeValue = calcHashCode();
          }
          return hashCodeValue;
     }

     public boolean equals(Object that) {
          if (!(that instanceof RemoteClientId)) {
               RemoteClientId rci = (RemoteClientId)that;
               return (rci.timeStampKey != timeStampKey) ? false : ((clientIpAddress == null) ? (rci.clientIpAddress == null) : clientIpAddress.equals(rci.clientIpAddress));
          }
          return false;
     }

     public void setClientIpAddress(String ip) {
          if (hashCodeValue == 0) {
               clientIpAddress = ip;
          }
     }

     public void setTimeStampKey(long timeStamp) {
          if (hashCodeValue == 0) {
               timeStampKey = timeStamp;
          }
     }

     public String getClientIpAddress() {
          return clientIpAddress;
     }

     public long getTimeStampKey() {
          return timeStampKey;
     }
}


Hope this helps,
Doron
0
 
LVL 3

Expert Comment

by:yasser_helmy
ID: 7143458
I think doron gave some very valuable info. I want to add some thing. If the equals() method returns true for any two objects, the hashCode() method of the two objects would logically return equal values.
The equals() method compares should compare the fields of the two objects and returns true if and only if the fields are equal.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 7143502
>>If the equals() method returns true for any two objects, the hashCode() method of the two objects would logically return equal values.

That should only be the case if (o1 == o2) == true

otherwise you would be contradicting doronb's observation

>>The 2nd thing to remember is that most object inherit their hashCode implementation from the java.lang.Object which simply returns the memory location of the java object in question

since two different [but equal()] objects can't have the same reference

>>The equals() method compares should compare the fields of the two objects and returns true if and only if the fields are equal.

Not necessarily *all* the fields. There may be some that are unequal that are of no importance at all to the client.
0
 
LVL 9

Expert Comment

by:doronb
ID: 7143516
Hi again,


A great source for discussion and examples about equals and hashCode is the book "EFFECTIVE JAVA Programming Language Guide by Joshua Bloch" displayed at http://java.sun.com/docs/books/effective/

Chapter 3, Item #8 talks EXACTLY about overriding the hashCode and equals methods.


Good luck,
Doron
0
 
LVL 9

Expert Comment

by:doronb
ID: 7143525
One concept that you must INSIST on is that if you're overriding hashCode, you should override equals and vice versa, NOT doing so is at the programmer's responsibility >;)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 7143902
>>
The hashCode() method must never be implemented by:

return super.hashCode();
>>

This is a little harsh doronb! Especially as the book you recommended by Joshua Bloch has the following code as an example for Chapter 5:

public final int hashCode() {
        return super.hashCode();
    }

However I agree that:

>>
super method is not going to change anything and supply a better hashCode than the super class would have.
>>

So you may as well allow the superinterface's hashCode() method to be called.

Since this hash got a bit theoretical in parts, perhaps : anuchoudhry would like clarification?
0
 
LVL 9

Expert Comment

by:doronb
ID: 7143954
Hi CEHJ,


Please note the "final" keyword in your example. I will explain its presence with an example:

class A {
  public int hashCode() {
    // Do some complex stuff, return value..
  }
}

class B extends A {
  public final int hashCode() {
    // Stop anyone from overriding
    // the hashCode method if
    // inherited from class B!
    return super.hashCode();
  }
}

There is one more case where I would use super.hashCode and that is if my hashCode relies on my super-class hashCode. I can't imagine right now some problem that would make me do that, but I'm sure one can be found. :)

Doron
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 7143974
Yes, I see. Of course! Thanks doronb.
0
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 7146743
Hi,

> This is a little harsh doronb! Especially as the book you recommended by Joshua Bloch has the following code as an example for Chapter 5:
Note that Chapter 5 is titled 'Substitutes for C Constructs'. I guess you took your sample from the Item 21: Replace enum constructs with classes. In that spacific context, Object equals() and hashCode() behavior is correct, because each 'enum' value has it's own identity, so == comparison of such objects is OK (Object.equals() implementation is almost equivalent to pointer equality, it only doesn't work for null).

anuchoudhry,
Note that you need equals() and hashCode() implementation only if you need to compare your objects or use them as HashMap keys (or store in HashSet, it's almost the same). java.lang.Object provides default implementation of equals() which simply compares references, and hashCode() returns some kind of address value (you can't turn it into reference though).

Read Object.eqauls() and Object.hashCode() for the rules:

The equals method implements an equivalence relation:

equals() rules:

- It is reflexive: for any reference value x, x.equals(x) should return true.
- It is symmetric: for any reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
- It is transitive: for any reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
- It is consistent: for any reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified.
- For any non-null reference value x, x.equals(null) should return false.

The general contract of hashCode is:

- Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
- If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
- It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

Regards,
Igor Bazarny,
Brainbench MVP for Java 1
0
 
LVL 35

Expert Comment

by:girionis
ID: 8917100
No comment has been added lately, so it's time to clean up this TA.

I will leave a recommendation in the Cleanup topic area that this question is:

- points to doronb

Please leave any comments here within the
next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER !

girionis
Cleanup Volunteer
0

Featured Post

What Is Transaction Monitoring and who needs it?

Synthetic Transaction Monitoring that you need for the day to day, which ensures your business website keeps running optimally, and that there is no downtime to impact your customer experience.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question