Dictionary<TKey,TValue>
/*
* 先将 key 和 bucket 的长度一起,经过简单的 hash 算法计算出元素应该放在哪个 bucket .
* 但是,元素并不是放在 bucket 里面的,bucket 只是对元素存放位置的第一次计算, 它其实是为了解决 hash 冲突设计的,它并不存放我们添加的元素.
* 当确定了 bucket 后,再将元素存放在 Entry[] 中, 这个数组才是实际存放元素的容器.并且所有元素都存放在这个数组中.
* 因此,当 Dictionary 需要扩容的时候,不仅 bucket 需要扩容, Entry[] 也需要扩容,当然,数组长度是不能变的,肯定是新建一个容量更大的,然后 copy 一份老的数据过去.
* 前面说了,hash 会冲突,比如 1%3=1 , 4%3=1 ,那么这时候,1 和 4 这两个数作为 key ,就会导致 hash 冲突,它们两个通过计算后,都会选择 bucket[1] 这个"桶",
* 那么,问题来了,
* bucket[1] = ? , 如果没有 hash 冲突,这个值完全可以用来存储 key 对应的 value.但是现在有两个"相同的" key 对应的 value 都需要存到这里,怎么办呢?
* 答案是"栈"+"链表",之所以加个引号,是因为不是真正用的栈和链表,而是借用了它们的思想.
* bucket 里面存储的是当前 bucket "里面" 最后添加的那个元素在 Entry[] 中的下标.
* 比如,我们先添加一个 dic.Add(1,value) ,那么,这时候,Entry[] 就有1个元素了,Entry[0]
* 我们假设通过 hash 计算,这个键值对元素应该放在 bucket[1] 这个桶里面,因此这时候 bucket[0] = 0 ,等号右边的 0 表示 Entry[] 的下标.
* 我们再 Add(4,value),这时候,Entry[] 有2个元素,Entry[0] 和 Entry[1],
* 并且我们假设通过 hash 计算,这个键值对元素也应该放在 bucket[1] 这个桶里面,
* 那么,这时候 bucket[0] 就不在 = 0了,而是 = 1,
* 并且 Entry[1] 中的元素(Entry 类型)有个 next 字段,其值 = 0, 这个 0 就是 Entry[] 的索引,表示该元素的下个元素是 Entry[0] ,进一步说就是
* 桶1里面有两个元素,最上面的(第2次放进去的)是 Entry[1] ,第2个(第1次放进去的那个)是 Entry[0],并且通过 Entry[1] 是可以找到 Entry[0] 的.
* 到这里,突然发现 bucket 这个命名很形象.
* 桶有什么特点呢?桶就好比是一个栈,"先进后出",最先进去的在最下面.
* 也就是说,一个桶第一次装进去的那个元素的 next 永远 = -1
* 第2次进去的指向第1个,第3次进去的指向第2个......
* 感觉这个设计好巧妙!!!
*
*/
Dictionary<TKey,TValue>的更多相关文章
- convert NameValueCollection/Dictionary<string, object> to JSON string
public static class WebExtension { public static T Decode<T>(this RequestBase res) { Type type ...
- Dictionary<string, object>
Dictionary<string, object> dcic = JsonHelper.DataRowFromJSON(resultdepth); foreach (var depthk ...
- Dictionary<string, object>不区分大小写
Dictionary<string, object> dic = new Dictionary<string, object>(StringComparer.OrdinalIg ...
- Tuple<int, int> Dictionary<string, object>妙用
Tuple<int, int> Dictionary<string, object>妙用
- c# Dictionary<string, object> 转JSON字符串
JavaScriptSerializer jss = new JavaScriptSerializer(); Dictionary<string, object> dict = new D ...
- MVC object htmlAttributes,IDictionary<string, object> htmlAttributes 写法
MVC object htmlAttributes:new {style="color:red",width="12px",height="10px& ...
- List<T>与Dictionary<string,T>频繁检索的性能差距
一直对LINQ简洁高效的语法青睐有加,对于经常和资料库,SQL语法打交道的C#开发者来说,LINQ无疑是一个非常不错的选择,当要在List<T>(T为一个普通对象)集合中查找满足某些条件的 ...
- MVC 自定义IModelBinder实现json参数转Dictionary<string, string>
IModelBinder的学习不算深入,现在用它来实现一个json转Dictionary<string, string> 一.原始json转Dictionary<string, st ...
- QueryString to Dictionary<string, string>
public class ModelConvertHelper<T> where T : new() {// 此处一定要加上new() public static IList<T&g ...
- 分页查询和分页缓存查询,List<Map<String, Object>>遍历和Map遍历
分页查询 String sql = "返回所有符合条件记录的待分页SQL语句"; int start = (page - 1) * limit + 1; int end = pag ...
随机推荐
- 安装HDP时的报错信息
1,安装ambari时报错:Bootstrap process timed out. It will be destroyed. 报错原因:/etc/sudoers文件中未设置免密权限 解决办法:ha ...
- Google guava 中的Monitor
synchronized 自从Java提供了多线程编程,我们经常需要处理这样的情况:在特定的时间,我们需要限制访问,确保只有一个线程访问我们的代码.Java提供了同步关键字synchronized来实 ...
- 巧妙利用JQuery和Servlet来实现跨域请求
在网上看到很多的JQuery跨域请求的文章,比较有意思.这里我发表一个Servlet与JQuery配置实现跨域的代码,供大家参考.不足之处请指教 原理:JavaScript的Ajax不可以跨域,但是可 ...
- 使用TortoiseGit时如何实现SSH免密码登录
1. Git配置 连接GIT服务器使用的是SSH连接,因此无密码登录,需要使用公钥和私钥. 1) 生成公钥/私钥 在Git Shell中输入ssh-keygen命令,直接回车使用默认 ...
- 2008 Round 1A C Numbers (矩阵快速幂)
题目描述: 请输出(3+√5)^n整数部分最后3位.如果结果不超过2位,请补足前导0. 分析: 我们最容易想到的方法肯定是直接计算这个表达式的值,但是这样的精度是不够的.朴素的算法没有办法得到答案.但 ...
- [\u4e00-\u9fa5] //匹配中文字符
[\u4e00-\u9fa5] //匹配中文字符 ^[1-9]\d*$ //匹配正整数^[A-Za-z]+$ //匹配由26个英文字母组成的字符串^[A-Z]+$ //匹配由26 ...
- 多个id或class属性相同的元素绑定事件
<td class="tools"><a href="javascript:void(0);" status="0" na ...
- JAVA封装消息中间件调用一(kafka生产者篇)
这段时间因为工作关系一直在忙于消息中间件的发开,现在趁着项目收尾阶段分享下对kafka的一些使用心得. kafka的原理我这里就不做介绍了,可参考http://orchome.com/kafka/in ...
- beego学习笔记(4):开发文档阅读(1)
1.beego的设计是高度模块化的.每个模块,都可以单独使用.一共八大模块: cache;session;log;orm;context;httplibs;toolbox 2.beego的执行逻辑 3 ...
- Effective C++学习进阶版
记得前段时间又一次拿起<Effective C++>的时候,有种豁然开朗的感觉,所以翻出了我第一遍读时做的笔记.只做参考以及查阅之用.如有需要请参阅<Effective C++> ...