引用:

https://www.cnblogs.com/InCerry/p/10325290.html

字典原理分析:

1、用数组存元素,元素的结构体存hashCode、next、key、value。 初始化的时候该数组的长度和桶的长度都是size(后续存在remove操作,数组并不是一一对应字典元素)

2、add操作通过hash算法获得hashCode,求余获得桶位置。元素实体该赋值赋值,桶记录实体idx,如果桶冲突,利用实体的next用单链表解决。(链地址法)

3、remove操作,处理对应桶的链表,重置元素实体的各种字段。记录freeCount, count-freeCount==真实字典长度

4、其他细节:字典有个版本字段,增删改都会导致+1。(freeList;//记录最近一次remove的实体的idx)

      private void Resize(int newSize, bool forceNewHashCodes) {
Contract.Assert(newSize >= entries.Length);
//创建新的桶数组
int[] newBuckets = new int[newSize];
for (int i = 0; i < newBuckets.Length; i++) newBuckets[i] = -1;
//创建新的实体数组
Entry[] newEntries = new Entry[newSize];
//拷贝实体数组
Array.Copy(entries, 0, newEntries, 0, count);
//强制重新计算hashCode
if(forceNewHashCodes) {
for (int i = 0; i < count; i++) {
if(newEntries[i].hashCode != -1) {
newEntries[i].hashCode = (comparer.GetHashCode(newEntries[i].key) & 0x7FFFFFFF);
}
}
}
for (int i = 0; i < count; i++) {
if (newEntries[i].hashCode >= 0) {
//当hashCode大于-1(该元素有值),赋值桶的值
int bucket = newEntries[i].hashCode % newSize;
newEntries[i].next = newBuckets[bucket];
newBuckets[bucket] = i;
}
}
buckets = newBuckets;
entries = newEntries;
}

Find操作

       private int FindEntry(TKey key) {
...
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
//对应的桶拿到该桶位置最近一次的实体的idx, 遍历桶位置的单链表,如果对应的key和参数key相等,则return
for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next) {
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
}
...
return -1;
}

C# Dictionary的底层实现解析的更多相关文章

  1. ArrayList底层代码解析笔记

    通过底层代码可以学习到很多东西: public class ArrayList<E> extends AbstractList<E> implements List<E& ...

  2. Spring Cloud底层原理解析

    概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓 ...

  3. ArrayList 源码底层实现解析 基于1.8

    ArrayList 介绍 ArrayList是一种线性数据结构,它的底层是用数组实现的,是动态数组.与Java中的数组相比,它的容量能动态增长.源代码里有解释.当创建一个数组的时候,就必须确定它的大小 ...

  4. git plumbing 更加底层命令解析-深入理解GIT

    原文: http://rypress.com/tutorials/git/plumbing 本文详细介绍GIT Plumbing--更加底层的git命令,你将会对git在内部是如何管理和呈现一个项目r ...

  5. 利用Redisson实现分布式锁及其底层原理解析

    Redis介绍 参考地址:https://blog.csdn.net/turbo_zone/article/details/83422215 redis是一个key-value存储系统.和Memcac ...

  6. LinkedList底层代码解析笔记

    LinkedList是属于Sequence List,故遍历是用迭代器更快; LinkedList继承自AbstractSequenceList.实现了List及Deque接口.其实AbstractS ...

  7. python 集合(set)和字典(dictionary)的用法解析

    Table of Contents generated with DocToc ditctaionary and set hash 介绍 集合-set 创建 操作和访问集合的元素 子集.超集.相对判断 ...

  8. git的核心命令使用和底层原理解析

    文章目录: GIT体系概述 GIT 核心命令使用 GIT 底层原理 一.GIT体系概述 GIT 与 svn 主要区别: 存储方式不一样 使用方式不一样 管理模式不一样 1.存储方式区别 GIT把内容按 ...

  9. 从HBase底层原理解析HBASE列族不能设计太多的原因?

    在之前的文章<深入探讨HBASE>中,笔者详细介绍了: HBase基础知识(包括简介.表结构).系统架构.数据存储 WAL log和HBase中LSM树的应用 HBase寻址机制 mino ...

随机推荐

  1. String 类中常用方法

    序号 方法定义 类型 描述 1 public String(char[] value) 构造 直接将一个字符数组变为一个字符串 2 public String(char[] value,int off ...

  2. Python按顺序读取文件夹中文件

    参考资料: https://blog.csdn.net/qq_22227123/article/details/79903116 https://blog.csdn.net/merdy_xi/arti ...

  3. URL is not registered (Settings | Languages & Frameworks | Schemas and DTDs)

    File - Settings - Schemas and DTDS时,选中报错的地址,然后Ctrl+alt+s打开设置(或者右键 -> setting)找到 把报错的地址填入就可以了,最后应用 ...

  4. [ C++ ] 勿在浮沙筑高台 —— 内存管理(18~31p) std::alloc

    部分内容个人感觉不是特别重要,所以没有记录了.其实还是懒 embedded pointers 把对象的前四字节当指针用. struct obj{ struct obj *free_list_link; ...

  5. 弹性配置为构建提速 - CODING & 腾讯云 CVM 最佳实践

    CODING 中提供了内置云主机用来执行持续集成(CI)中的构建计划,能够胜任大部分构建任务.但如果碰上了大型项目的构建,或者需要在本地服务器生成构建成果,单个计算资源就显得有点捉急了.针对这一部分需 ...

  6. ajax前后端交互原理(7)

    7.ajax函数封装 7.1.实例引入 需求: 每秒钟请求一次服务器 获取到数据 实现: 把ajax进行封装 <!DOCTYPE html> <html> <head&g ...

  7. Flutter 中那么多组件,难道要都学一遍?

    在 Flutter 中一切皆是 组件,仅仅 Widget 的子类和间接子类就有 350 多个,整理的 Flutter组件继承关系图 可以帮助大家更好的理解学习 Flutter,回归正题,如此多的组件到 ...

  8. Kali Day1

    一.最新版本的Kali Linux的账号名和密码都是kali. 如何切换root  步骤如下: 1. 设置密码 sudo passwd root 2. 切换身份 su 3. 图示 二.快捷键 1. K ...

  9. 使用Xmanager连接linux,操作“xhost +”时出现类似“xhost: unable to open display "192.168.1.1811:1.0" ”问题的解决

    远程连接linux服务器时,有的时候需要把服务器上的图形界面投影到本地来进一步操作,比如linux下安装oracle时就需要在oracle用户下允许视图状态投影到本地,这需要使用命令: xhost + ...

  10. SpringBoot-读取classpath下文件

    文章目录 开发过程中,必不可少的需要读取文件,对于打包方式的不同,还会存在一些坑,比如以jar包方式部署时,文件都存在于jar包中,某些读取方式在开发工程中都可行,但是打包后,由于文件被保存在jar中 ...