NSDictionary的哈希值

Tob*_*zer 10 cocoa objective-c nsdictionary

我遇到了一个问题,我为不同的词典获得了相同的哈希值.也许我做了一些明显错误的事情,但我认为,具有不同内容(也就是不相等的对象)的对象应该具有不同的哈希值.

NSDictionary *dictA = @{ @"foo" : @YES };
NSDictionary *dictB = @{ @"foo" : @NO };

BOOL equal = [dictA hash] == [dictB hash];

NSAssert(!equal, @"Assuming, that different dictionaries have different hash values.");
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?

ken*_*ytm 23

无法保证两个不同的对象具有不同的哈希值.

CoreFoundation的最新开源版本中,CFDictionary的哈希值(相当于NSDictionary)定义为:

static CFHashCode __CFDictionaryHash(CFTypeRef cf) {
    return __CFBasicHashHash((CFBasicHashRef)cf);
}
Run Code Online (Sandbox Code Playgroud)

__CFBasicHashHash定义为:

__private_extern__ CFHashCode __CFBasicHashHash(CFTypeRef cf) {
    CFBasicHashRef ht = (CFBasicHashRef)cf;
    return CFBasicHashGetCount(ht);
}
Run Code Online (Sandbox Code Playgroud)

这只是集合中存储的条目数.换句话说,两个[dictA hash][dictB hash]的哈希值都是1,即字典中的条目数.

虽然这是一个非常糟糕的哈希算法,但CF在这里没有做错任何事情.如果您需要更准确的哈希值,可以在Obj-C类别中自行提供.

  • **有一个很好的理由以这种方式实现.**由于NSArray是不可变的,它的[-copy]返回self.如果它将例如作为键添加到字典中,则即使数组中的对象发生突变,哈希也不会改变. (2认同)
  • @Patrick嗯,"数组的前32个指针值之和"也是不可变的.唯一的好理由是它的计算速度非常快,或者因为几乎没有人使用NSDictionary作为键,所以不要创建复杂的哈希. (2认同)

sup*_*org 5

使用仅包含整数、字符串等的字典,我将用作dict.description.hash快速代码。

  • 那么内容相同但排序不同的字典将导致不同的哈希值。 (2认同)