引用:

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. Linux基础:pkill命令总结

    本文只总结一些常用的用法,更详细的说明见man pkill和pkill --help. pkill命令 pkill命令:通过进程名杀死进程. 语法格式 Usage: pkill [options] & ...

  2. 全网最完整的Redis入门指导

    前言 本文提供全网最完整的Redis入门指导教程,下面我们从下载Redis安装包开始,一步一步的学习使用. 下载Redis 官网提供的Redis安装包是服务于Linux的,而我们需要在Window下使 ...

  3. 重装conda

    重装Conda是因为想重装tensorflow,结果竟然报了各种各样稀奇古怪的错误:我贴一下自己见过的报错 The environment is inconsistent, please check ...

  4. java递归遍历树结构目录

    目录实体 private int id; private int pid; private String name; 递归遍历方法 private void getTree(Menu menu ,Li ...

  5. Jmeter工具环境搭建

    Jmeter工具什么 1 多线程框架-支持多并发操作 2 用于对服务器模拟负载 3 支持web,数据库,FTP服务器系统的性能测试 4 开源,可二次定制开发 下载Java JDK 下载地址: http ...

  6. AliOS Things添加环境变量

    此电脑->属性->高级系统设置->环境变量->系统变量-新建.

  7. 第二章、Web中使用shiro(实现登陆)

    虽然Apache Shiro的核心设计目标允许它用于保护任何基于JVM的应用程序(如命令行应用程序,服务器守护程序,Web应用程序等),但本指南将着重讨论最常见的用例:确保运行的Web应用程序一个Se ...

  8. SpringCloud 入门(二)

    前文我们介绍了创建注册中心的过程以及配置,接下来我们再简单的创建一个客户端 基本操作和前文一样,不一样的是选择的依赖 然后下一步,修改启动类和配置,结构如下图 修改配置文件application-te ...

  9. Nginx负载均衡的详细配置 + Keepalived使用

    1,话不多说, 这里我们来说下很重要的负载均衡, 那么什么是负载均衡呢? 由于目前现有网络的各个核心部分随着业务量的提高,访问量和数据流量的快速增长,其处理能力和计算强度也相应地增大,使得单一的服务器 ...

  10. 部署rabbitMQ镜像集群实战测试

    部署rabbitMQ镜像集群 版本信息 rabbit MQ: 3.8.5 Erlang: 官方建议最低21.3 推荐22.x 这里用的是23 环境准备 主机规划 主机 节点 172.16.14.3 磁 ...