Hashing

  • Thread starter TT \(Tom Tempelaere\)
  • Start date
T

TT \(Tom Tempelaere\)

Hi,

My key is composed of two dates. What should I do to calculate the hash
value?

Can I just add the hashCode's of the two dates?

class DatePair
{
public Date d1;
public Date d2;
public int hashCode()
{
return d1.hashCode() + d2.hashCode();
}
}

Thanks,
Tom Tempelaere
 
X

xarax

TT (Tom Tempelaere) said:
Hi,

My key is composed of two dates. What should I do to calculate the hash
value?

Can I just add the hashCode's of the two dates?

class DatePair
{
public Date d1;
public Date d2;
public int hashCode()
{
return d1.hashCode() + d2.hashCode();
}
}

Thanks,
Tom Tempelaere

Depends on why you need hash codes and what
"equality" means for your DatePair. Unfortunately,
a hashCode is a 4-byte integer, which generally
resists attempts to provide "equality" for distinct
objects that are semantically equal.

e.g., if your d1 and d2 in a datePair1 instance
were interchanged for another datePair2 instance,
would the instances still be considered equal?

If so, then maybe a simple XOR of the hashcodes
would be enough.

public int hashCode()
{
return d1.hashCode() ^ d2.hashCode();
}

public boolean equals(Object obj)
{
DatePair dp;

dp = (DatePair) obj;
return (null != obj)
&& ((this == obj)
||
( (d1 == dp.d1) && (d2 == dp.d2) )
||
( (d1 == dp.d2) && (d2 == dp.d1) )
)
}
 
T

TT \(Tom Tempelaere\)

xarax said:
Depends on why you need hash codes and what
"equality" means for your DatePair. Unfortunately,
a hashCode is a 4-byte integer, which generally
resists attempts to provide "equality" for distinct
objects that are semantically equal.

How does java deal with overflow? Is that behaviour specified?
e.g., if your d1 and d2 in a datePair1 instance
were interchanged for another datePair2 instance,
would the instances still be considered equal?

The dates are fixed once the object is created (the code i posted is an
example)
If so, then maybe a simple XOR of the hashcodes
would be enough.
public int hashCode()
{
return d1.hashCode() ^ d2.hashCode();
}

So this is safe (ie returns decent has results)?
public boolean equals(Object obj)
{
DatePair dp;

dp = (DatePair) obj;
return (null != obj)
&& ((this == obj)
||
( (d1 == dp.d1) && (d2 == dp.d2) )
||
( (d1 == dp.d2) && (d2 == dp.d1) )
)
}

I was thinking in the lines of

public boolean equals(Object obj)
{
if(obj!=null && obj instanceof DatePair)
{
DatePair other = (DatePair) obj;
return other.d1.equals( d1 ) && other.d2.equals( d2 );
}
return false;
}

Tom.
 
E

Eric Jablow

TT \(Tom Tempelaere\) said:
How does java deal with overflow? Is that behaviour specified?


The dates are fixed once the object is created (the code i posted is an
example)

This isn't best. A DatePair made from today and tomorrow would have the
same hashcode as one made from tomorrow and today. Read Bloch's
Effective java, which recommends something like:

return 37L * d1.hashCode() + d2.hashCode();

It's important that the factor be a prime.
I was thinking in the lines of

public boolean equals(Object obj)
{
if(obj!=null && obj instanceof DatePair)
{
DatePair other = (DatePair) obj;
return other.d1.equals( d1 ) && other.d2.equals( d2 );
}
return false;
}

The null check isn't necessary. null is never an instanceof anything.
But consider checking the getClass() of each instead:


public boolean equals(Object obj)
{
if (obj == null || getClass() != obj.getClass()) return false;
DatePair other = (DatePair) obj;
return other.d1.equals( d1 ) && other.d2.equals( d2 );
}

I'm assuming that you made the fields public for brevity on USENET.

Also, consider the Jakarta Commons-Lang EqualsBuilder helper class.
 
T

TT \(Tom Tempelaere\)

Eric Jablow said:
This isn't best. A DatePair made from today and tomorrow would have the
same hashcode as one made from tomorrow and today. Read Bloch's
Effective java, which recommends something like:

return 37L * d1.hashCode() + d2.hashCode();

It's important that the factor be a prime.

What happens if this overflows? Will java throw an exception?
The null check isn't necessary. null is never an instanceof anything.
But consider checking the getClass() of each instead:


public boolean equals(Object obj)
{
if (obj == null || getClass() != obj.getClass()) return false;
DatePair other = (DatePair) obj;
return other.d1.equals( d1 ) && other.d2.equals( d2 );
}

Why is this better than my version?
I'm assuming that you made the fields public for brevity on USENET.

Also, consider the Jakarta Commons-Lang EqualsBuilder helper class.

What is that?

Tom.
 
T

Tony Morris

It's important that the factor be a prime.
What happens if this overflows? Will java throw an exception?
No.
http://www.linux-mag.com/downloads/2003-03/puzzlers/
contains a trivia question regarding this.

Why is this better than my version?

Your version does not honour the equals contract, it fails in a few areas.
@see java.lang.Object#equals(Object)
@see "Effective Java Programming", Joshua Bloch (there is a sample chapter
on java.sun.com regarding this issue

// A general rule, for any class X
class X
{
public boolean equals(Object o)
{
if(this == o)
{
return true;
}

if(o == null)
{
return false;
}

if(this.getClass() != o.getClass())
{
return false;
}

X x = (X)o;

// compare x members for equality and return appropriate value
}
}



--
Tony Morris
(BInfTech, Cert 3 I.T., SCJP[1.4], SCJD)
Software Engineer
IBM Australia - Tivoli Security Software
Home : +61 7 5502 7987
Work : +61 7 5552 4076
Mobile : 0408 711 099
(2003 VTR1000F)
 
T

TT \(Tom Tempelaere\)

[...]
No.
http://www.linux-mag.com/downloads/2003-03/puzzlers/
contains a trivia question regarding this.



Your version does not honour the equals contract, it fails in a few areas.
@see java.lang.Object#equals(Object)
@see "Effective Java Programming", Joshua Bloch (there is a sample chapter
on java.sun.com regarding this issue

// A general rule, for any class X
class X
{
public boolean equals(Object o)
{
if(this == o)
{
return true;
}

if(o == null)
{
return false;
}

if(this.getClass() != o.getClass())
{
return false;
}

X x = (X)o;

// compare x members for equality and return appropriate value
}
}

Thank you Tony.
Tom.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top