美文网首页
iOS hash函数与isEqual方法思考

iOS hash函数与isEqual方法思考

作者: Rokkia | 来源:发表于2018-06-26 11:56 被阅读35次

    说到hash函数,我们就需要了解一下Hash表,那么什么是hash表呢,在我的理解就是一个数组。通过hash函数将字符串等元素转换成一串数字,将这串数字与数组的长度取余当做数组的下标。对应的数组空间来存储这个元素。这样做有什么好处呢,好处在于我们可以使用O(1)的速度来获取到某一个值。 关于hash的理解可以看一下这篇文章 深入理解哈希表

    存储基本可以分为下面是哪个步骤(这段话来自于上面的那篇文章,很好的总结了存储过程):

    1. 根据 key 计算出它的哈希值 h。
    2. 假设箱子的个数为 n,那么这个键值对应该放在第 (h % n) 个箱子中。
    3. 如果该箱子中已经有了键值对,就使用开放寻址法或者拉链法解决冲突。

    拉链法hash表的样子就会变成类似这样。


    拉链法hash表(图片来自网络).png

    OK, 基础已经铺垫完成,让我们来看一下iOS中的使用。当我们去比较两个两个对象是否相等的时候,我们无法使用 == 来比较,原因很简单,当我们使用 == 来比较两个对象的时候,我们比较的是两个对象的内存地址,这样一来肯定无法比较。这里参考文章iOS开发之不要告诉我你真的懂isEqual与hash!
    于是,当我们想去比较两个对象是否相等的时候,我们需要重写isEqual方法。

    -(BOOL)isEqual:(id)object{
        if (self == object) {
            return YES;
        }
        if (![self isKindOfClass:[RokkiaNetWorking class]]) {
            return NO;
        }
        return [self isEqualToRokkiaNetWorking:(RokkiaNetWorking *)object];
    }
    -(BOOL)isEqualToRokkiaNetWorking:(RokkiaNetWorking *)object{
        if (!object) {
            return NO;
        }
        BOOL isNameEqual = //比较
        BOOL isHttpEqual = //比较
        return isNameEqual && isHttpEqual;
    }
    

    当我们实验的时候,你会发现很完美,但是我们为什么还要使用重写hash函数呢。
    当我们使用NSSet的时候,我们会发现当我们传入两个isEqual为True的对象时,我们拿到的set count = 2,因为我们会将每个对象的地址进行hash所以得到的地址会是两个,作为isEqual的对象set中我们无需存储两边。所以我们可以重写hash方法。

    In reality, a simple XOR over the hash values of critical properties is sufficient 99% of the time(对关键属性的hash值进行位或运算作为hash值)

    - (NSUInteger)hash {
        return [self.name hash] ^ [self.birthday hash];
    }
    

    相关文章

      网友评论

          本文标题:iOS hash函数与isEqual方法思考

          本文链接:https://www.haomeiwen.com/subject/avypyftx.html