Implementing -hash for -isEqual

  • I'm having some trouble finding a "best practices" sort of document for
    overriding -hash for the purpose of overriding -isEqual.

    I have a custom class, and I want objects of that class to be
    considered equal if they share a value for a particular member. The
    docs say that -hash has to return the same integer value for both
    objects if isEqual return YES, but I haven't been able to find a sample
    implementation of hash that serves this purpose.

    The two articles I found:

    This has an overview of the issue, but doesn't provide a sample -hash
    override:
    http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaObjects/
    Articles/Introspection.html

    This provides some details on has, but it's more about optimizing
    existing NSObject hash functionality rather than providing new
    behavior:
    http://www.mulle-kybernetik.com/artikel/Optimization/opti-7.html

    I couldn't find anything in Scott's book.

    Suggestions? I'm just looking for a template of some sort. Am I making
    this harder than it needs to be?

    Thanks,

        - Scott

    --
    Tree House Ideas
    http://treehouseideas.com/
  • On Dec 18, 2003, at 2:14 PM, Scott Stevenson wrote:

    > I'm having some trouble finding a "best practices" sort of document
    > for overriding -hash for the purpose of overriding -isEqual.
    >
    > I have a custom class, and I want objects of that class to be
    > considered equal if they share a value for a particular member. The
    > docs say that -hash has to return the same integer value for both
    > objects if isEqual return YES, but I haven't been able to find a
    > sample implementation of hash that serves this purpose.
    >

    What are the member types?  If they are a class themselves, easiest
    was is to implement hash to return [member hash].  This works fine,
    because whereas objects that are equal must have the same hash, two
    objects having the same hash does NOT imply they are equal.
  • On Dec 18, 2003, at 11:35 AM, T Reaves wrote:

    >> I have a custom class, and I want objects of that class to be
    >> considered equal if they share a value for a particular member. The
    >> docs say that -hash has to return the same integer value for both
    >> objects if isEqual return YES, but I haven't been able to find a
    >> sample implementation of hash that serves this purpose.
    >
    > What are the member types?

    NSStrings.

        - Scott

    --
    Tree House Ideas
    http://treehouseideas.com/
  • >>> I have a custom class, and I want objects of that class to be
    >>> considered equal if they share a value for a particular member. The
    >>> docs say that -hash has to return the same integer value for both
    >>> objects if isEqual return YES, but I haven't been able to find a
    >>> sample implementation of hash that serves this purpose.
    >>
    >> What are the member types?
    >
    > NSStrings.

    Depends on what you want to achieve.

    1. You can do a XOR of each constituent type e.g. a ^ b ^ c ... hashes
    done with XOR are less likely than any other simple operator to have
    repeated values, so that ensures a good distribution of values.

    2. You can simply return the hash of one of your strings. This is
    faster since you don't have to get the hash of all your objects, but it
    is only worthwhile if that string is much more random than the other
    strings.

    Cheers, Glen Low

    ---
    pixelglow software | simply brilliant stuff
    www.pixelglow.com
  • Am 18.12.2003 um 23:43 schrieb Glen Low:

    >>>> I have a custom class, and I want objects of that class to be
    >>>> considered equal if they share a value for a particular member. The
    >>>> docs say that -hash has to return the same integer value for both
    >>>> objects if isEqual return YES, but I haven't been able to find a
    >>>> sample implementation of hash that serves this purpose.
    >>>
    >>> What are the member types?
    >>
    >> NSStrings.
    >

    Pick an instance variable that is very likely to contain some text and
    when it does contain text that it is very likely to be different in the
    first 8 or last 8 characters from other objects who should be
    considered not equal. Also it can't hurt to take a string that is
    likely to be larger than 5 characters and smaller than 4 K.

    Code it like this:

    - (unsigned int) hash
    {
        return( [myInstanceVariableOfChoice_ hash]);
    }

    If you can't find a string that fits the bill, figure a combination of
    instance variables, but the fewer the better. Code it then like this:

    - (unsigned int) hash
    {
        return( [myInstanceVariableOfChoice_ hash] ^
    [myOtherInstanceVariableOfChoice_ hash]);
    }

    If two objects that should be considered equal do not hash to the same
    value, that is BAD. If two objects that are disequal hash to the same
    value, that is not a problem if it doesn't happen too often
    statistically.

    Ciao
    Nat!

    I act professionally, when I get paid for it. - Unknown
  • On Dec 18, 2003, at 2:14 PM, Scott Stevenson wrote:

    > I'm having some trouble finding a "best practices" sort of document
    > for overriding -hash for the purpose of overriding -isEqual.

    There is a good discussion by Joshua Bloch, in his book "Effective
    Java", of implementing the Java hashCode() method, that I bet would
    translate pretty directly to Objective-C.  The chapter in question
    happens to be freely available online:
    <http://developer.java.sun.com/developer/Books/effectivejava/
    Chapter3.pdf
    >

    But it sort of depends upon all of the instance/member variables in
    your object also implementing a hash code method, and I don't know if
    the Apple-supplied libraries do or not.  I would read the PDF
    regardless, it's pretty solid advice.

    Erik