一言以蔽之:在OC中NSDictionary是使用hash表来实现key和value的映射和存储的。

那么问题来了什么是hash表呢?

哈希表(hash表): 又叫做散列表,是根据关键码值(key value)而直接访问的 数据结构 。也就是说它通过关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射叫做 函数 ,存放记录的 数组 叫做 哈希表 。

读到此处我们得到一个关键信息:所谓 哈希表就是一个数组 ,数组中每一个元素称为一个箱子(bin),箱子中存放的是键值对。看一个示意图就一目了然了:

hash表存储过程简单介绍:

  1. 根据key值计算出它的hash值h;
  2. 假设箱子的个数是n,那么键值对应该放在第(h%n)个箱子中。
  3. 如果该箱子中已经有了键值对,就是用开放寻址法或者拉链法解决冲突。使用拉链法解决哈希冲突时,每个箱子其实是一个链表,属于同一个箱子的所有键值对都会排列在链表中。

依此我们得出结论:OC中的字典其实是一个数组,数组中每一个元素同样为一个链表实现的数组,也就是数组中套数组。

那么对应在oc中字典是如何进行存储的呢?

在oc中每一个对象创建时,都默认生成一个hashCode,也就是经过hash算法生成的一串数字,当利用key去取字典中的value时,若是使用遍历或者二分查找等方法,效率相对较低,于是出现了根据每一个key生成的hashCode将键值对放到hasCode对应的数组中的指定位置,这样当用key去取值时,便不必遍历去获取,既可以根据hashCode直接取出。因为hashCode的值过大,或许经过取余获取一个较小的数字,假如是对999进行取余运算,那么得到的结果始终处于0-999之间。但是,这样做的弊端在于取余所得到的值,可能是相同的,这样可能导致完全不相干的键值对被新的键值对(取余后值key相等)所覆盖,于是出现了数组中套链表实现的数组。这样,key值取余得到值相等的键值对,都将保存在同一个链表数组中,当查找key对应的值时,首先获取到该链表数组,然后遍历数组,取正确的key所对应的值即可。

转自:https://www.codercto.com/a/20469.html

最新文章

  1. windows2012 iis配置
  2. SpringMVC@RequestBody小细节
  3. 添加 index_combine hint的索引
  4. 修改linux系统时间、rtc时间以及时间同步
  5. oracle 创建字段自增长——两种实现方式汇总(转)
  6. Beginning Python From Novice to Professional (5) - 条件与循环
  7. Java实现 中文转换成Unicode编码 和 Unicode编码转换成中文
  8. ehcache模糊批量移除缓存
  9. C语言最后一次作业--总结报告
  10. 高并发架构系列:MQ消息队列的12点核心原理总结
  11. elastichd安装部署
  12. HTTP 协议基础概念和报文结构
  13. spring boot整合shiro后,部分注解(Cache缓存、Transaction事务等)失效的问题
  14. redis 配置文件翻译
  15. Kettle进行数据迁移(ETL)
  16. XML 文档结构必须从头至尾包含在同一个实体内
  17. 第一章 程序设计和C语言(笔记)
  18. 20155328 《Java程序设计》实验一(Java开发环境的熟悉) 实验报告
  19. SilverLight高亮显示文本
  20. 多继承c3算法

热门文章

  1. Codeforces Round #432 (Div. 2)
  2. POJ Treasure Exploration 【DAG交叉最小路径覆盖】
  3. [19/03/16-星期六] 常用类_Date时间类&DateFormat类
  4. 【luogu P2194 HXY烧情侣】 题解
  5. 节约内存:Instagram的Redis实践
  6. python 用selenuim判断页面是否全部加载完成,并且加上最大时长,超过时长报错
  7. Docker 入坑教程笔记
  8. django+xadmin在线教育平台(十七)
  9. python中的"is"与"=="比较
  10. 百度地图API定位+显示位置