Hashing

Discussion in 'Java' started by TT \(Tom Tempelaere\), Feb 5, 2004.

  1. 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
     
    TT \(Tom Tempelaere\), Feb 5, 2004
    #1
    1. Advertising

  2. TT \(Tom Tempelaere\)

    xarax Guest

    "TT (Tom Tempelaere)" <_N_> wrote in message
    news:w7wUb.578$Z%-ops.be...
    > 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) )
    )
    }
     
    xarax, Feb 5, 2004
    #2
    1. Advertising

  3. "xarax" <> wrote in message
    news:h0xUb.12834$...
    > "TT (Tom Tempelaere)" <_N_> wrote in

    message
    > news:w7wUb.578$Z%-ops.be...
    > > 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.


    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.
     
    TT \(Tom Tempelaere\), Feb 5, 2004
    #3
  4. TT \(Tom Tempelaere\)

    Eric Jablow Guest

    In article <rDxUb.681$-ops.be>,
    "TT \(Tom Tempelaere\)" <_N_> wrote:

    > "xarax" <> wrote in message
    > news:h0xUb.12834$...
    > > 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();
    > > }

    >


    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.

    --
    Respectfully,
    Eric Jablow
     
    Eric Jablow, Feb 6, 2004
    #4
  5. "Eric Jablow" <> wrote in message
    news:...
    > In article <rDxUb.681$-ops.be>,
    > "TT \(Tom Tempelaere\)" <_N_> wrote:
    > > "xarax" <> wrote in message
    > > news:h0xUb.12834$...

    [...]
    > > > If so, then maybe a simple XOR of the hashcodes
    > > > would be enough.
    > > > public int hashCode()
    > > > {
    > > > return d1.hashCode() ^ d2.hashCode();
    > > > }

    > >

    >
    > 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?

    > >
    > > 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 );
    > }


    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.

    > --
    > Respectfully,
    > Eric Jablow
     
    TT \(Tom Tempelaere\), Feb 6, 2004
    #5
  6. TT \(Tom Tempelaere\)

    Tony Morris Guest

    > > 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.


    > > 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?


    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)
     
    Tony Morris, Feb 8, 2004
    #6
  7. "Tony Morris" <> wrote in message
    news:40260855$0$5224$...
    [...]
    > > 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.
    >
    >
    > > > 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?

    >
    > 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


    Thank you Tony.
    Tom.
     
    TT \(Tom Tempelaere\), Feb 8, 2004
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guadala Harry
    Replies:
    4
    Views:
    377
    Steve C. Orr [MVP, MCSD]
    Sep 12, 2004
  2. =?Utf-8?B?QnJpYW4=?=

    Password Hashing and User Authentication

    =?Utf-8?B?QnJpYW4=?=, Jun 6, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    379
    =?Utf-8?B?QnJpYW4=?=
    Jun 6, 2005
  3. Showjumper

    Hashing Passwords

    Showjumper, Dec 21, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    380
    Showjumper
    Dec 22, 2005
  4. Password hashing

    , Apr 15, 2004, in forum: Java
    Replies:
    3
    Views:
    2,370
    Roedy Green
    Apr 15, 2004
  5. Mikke
    Replies:
    7
    Views:
    11,225
    Mark Thornton
    May 24, 2004
Loading...

Share This Page