NSDictionary实现原理-ios哈希hash和isEqual
NSDictionary实现原理-ios哈希hash和isEqual
NSDictionary(字典)是使用 hash表来实现key和value之间的映射和存储的, hash函数设计的好坏影响着数据的查找访问效率。数据在hash表中分布的越均匀,其访问效率越高。而在Objective-C中,通常都是利用NSString 来作为键值,其内部使用的hash函数也是通过使用 NSString对象作为键值来保证数据的各个节点在hash表中均匀分布。
见NSDictionary中最常用的一个方法原型:
- - (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
既然知道了作为 key 值,必须遵循 NSCopying 协议,说明除了 NSString 对象之外,我们还可以使用其他类型对象来作为 NSDictionary 的 key值。不过这还不够,作为 key 值,该类型还必须继承于 NSObject 并且要重载一下两个方法:
- - (NSUInteger)hash;
- - (BOOL)isEqual:(id)object;
在OC中,如果自定义类,则要考虑赋值、持久化保存、保存到其它容器中等各种情况的对象复制和比较,下面是一个比较全面的自定义例子,在此仅作记录:
自定义类:
KeyValuePairs.h:
- #import <Foundation/Foundation.h>
- @interface KeyValuePairs: NSObject <NSCopying>
- @property (nonatomic,strong)NSString *identifier;
- @property (nonatomic,strong)NSString *name;
- @end
- #import "KeyValuePairs.h"
- @implementation KeyValuePairs
- - (id)copyWithZone:(NSZone *)zone
- {
- KeyValuePairs *kvp = [[[self class] allocWithZone:zone] init];
- kvp.identifier = self.identifier;
- kvp.name = self.name;
- return kvp;
- }
- - (BOOL)isEqualToKeyValuePairs:(KeyValuePairs *)kvp{
- if (!kvp) {
- return NO;
- }
- BOOL haveEqualName = (!self.name && !kvp.name) || [self.name isEqualToString:kvp.name];
- BOOL haveEqualIdentifier = (!self.identifier && !kvp.identifier) || [self.identifier isEqualToString:kvp.identifier];
- return haveEqualName && haveEqualIdentifier;
- }
- #pragma mark -NSObject
- -(BOOL)isEqual:(id)object{
- if (self == object) {
- return YES;
- }
- if (![object isKindOfClass:[KeyValuePairs class]]) {
- return NO;
- }
- return [self isEqualToKeyValuePairs:(KeyValuePairs *)object];
- }
- - (NSUInteger)hash {
- return [self.name hash] ^ [self.identifier hash];
- }
- @end
测试:
- NSMutableDictionary *namesWillUpdateDic = [[NSMutableDictionary alloc] init];
- NSMutableArray *names = [[NSMutableArray alloc] init];
- for (int i = 0; i<1000; i++) {
- NSString *name = [NSString stringWithFormat:@"%d_zhangsan",i];
- NSString *identifier = [NSString stringWithFormat:@"%d_identifier",i];
- NSString *strObj = [NSString stringWithFormat:@"%d_strObj",i];
- KeyValuePairs *kvp = [[KeyValuePairs alloc] init];
- kvp.identifier = identifier;
- kvp.name = name;
- [namesWillUpdateDic setObject:strObj forKey:kvp];
- [names addObject:kvp];
- }
- for (int j = 0; j<1000; j++) {
- int index = arc4random()%1000;
- KeyValuePairs *kvp = [names objectAtIndex:index];
- NSString *strObj = [namesWillUpdateDic objectForKey:kvp];
- NSString *msg = [NSString stringWithFormat:@"index:%d,identifier:%@,email:%@,strObj:%@",index,kvp.identifier,kvp.name,strObj];
- NSLog(@"%@",msg);
- }
NSDictionary实现原理-ios哈希hash和isEqual的更多相关文章
- iOS判断对象相等 重写isEqual、isEqualToClass、hash
相等的概念是探究哲学和数学的核心,并且对道德.公正和公共政策的问题有着深远的影响. 从一个经验主义者的角度来看,两个物体不能依据一些观测标准中分辨出来,它们就是相等的.在人文方面,平等主义者认为相等意 ...
- redis 哈希(hash)函数
哈希(hash)函数 hSet 命令/方法/函数 Adds a value to the hash stored at key. If this value is already in the has ...
- redist命令操作(二)--哈希Hash,列表List
1.Redis 哈希(Hash) 参考菜鸟教程:http://www.runoob.com/redis/redis-hashes.html Redis hash 是一个string类型的field和v ...
- Redis中的哈希(Hash)
Redis 哈希(Hash) Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象. Redis 中每个 hash 可以存储 232 - 1 键值 ...
- 大话Java中的哈希(hash)结构(一)
o( ̄▽ ̄)d 小伙伴们在上网或者搞程序设计的时候,总是会听到关于“哈希(hash)”的一些东西.比如哈希算法.哈希表等等的名词,那么什么是hash呢? 一.相关概念 1.hash算法:一类特殊的算法 ...
- Python操作redis系列以 哈希(Hash)命令详解(四)
# -*- coding: utf-8 -*- import redis #这个redis不能用,请根据自己的需要修改 r =redis.Redis(host=") 1. Hset 命令用于 ...
- Redis 命令,键(key),字符串(String),哈希(Hash),列表(List),集合(Set)(二)
Redis 命令 Redis 命令用于在 redis 服务上执行操作. 要在 redis 服务上执行命令需要一个 redis 客户端.Redis 客户端在我们之前下载的的 redis 的安装包中. ...
- 哈希--Hash,“散列”/“哈希”
哈希 Hash,翻译“散列”,音译为“哈希”,把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是散列值的空间通常远小于输入的空间,不同的输入可能会散 ...
- 区块链 - 哈希(Hash)
章节 区块链 – 介绍 区块链 – 发展历史 区块链 – 比特币 区块链 – 应用发展阶段 区块链 – 非对称加密 区块链 – 哈希(Hash) 区块链 – 挖矿 区块链 – 链接区块 区块链 – 工 ...
随机推荐
- JavaSE——线程通信
线程通信: 如果线程A和线程B持有同一个MyObject类的对象object,这两个线程会去调用不同的方法,但是它们是同步执行的,比如:线程B需要等待线程A执行完了methodA()方法之后,它才能执 ...
- JetBrains PhpStorm 2017.2 x64 激活
使用方法:激活时选择License server 填入http://idea.imsxm.com 点击Active即可
- 加速JDBC的快捷方法
JAVA 应用必须通过 JDBC 从数据库中取数,有时候我们会发现,数据库的负担一点也不重而且 SQL 很简单,但取数的速度仍然很慢.仔细测试会发现,性能瓶颈主要在 JDBC 上,比如 MySQL 的 ...
- 构建第一个SpringBoot工程
学习和使用 SpringBoot 有一段时间了,现在开始陆陆续续会总结归纳 SpringBoot 学习中遇到的相关知识点. SpringBoot 设计目的是用来简化新Spring应用的初始搭建以及开发 ...
- 转:检查c#代码内存泄露工具-CLR Profiler工具使用
大家都知道.net有一套自己的内存(垃圾)回收机制,除非有一些数据(方法)长期占有内存不随着垃圾回收功能而释放内存,这样就造成了我们经常说的内存泄露.内存持续增长得不到释放等问题导致APS.NET网站 ...
- C语言中的数组与指针
1. 数组的初始化 数组的初始化方法有很多,常用的方法有 定义时初始化 ]={,,}; 或 ]={}; //未初始化的元素全为0: 定义后遍历赋值初始化 int arr[3]; for(int i=0 ...
- 15 Top Paying IT Certifications In 2016: AWS Certified Solutions Architect Leads At $125K
Each of the five Amazon Web Services (AWS) certifications brings in an average salary of more than $ ...
- [技术] OIer的C++标准库 : 字符串库
引入 上次我在博客里介绍了OI中可能用到的STL中的功能, 今天我们接着来发掘C++标准库中能为OI所用的部分. 点击传送至我的上一篇系列博文 众所周知, OI中经常用到字符串相关的处理, 这时善用字 ...
- [LOJ 6030]「雅礼集训 2017 Day1」矩阵
[LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...
- PyQt5--QToggleButton
# -*- coding:utf-8 -*- ''' Created on Sep 20, 2018 @author: SaShuangYiBing Comment: '' import sys fr ...