本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文链接博客园蜗牛 cnblogs.com\tdws .

首先提供一种获取hashCode的方法,是一种比较受欢迎的方式,该方法参照了一位园友的文章,链接在尾部给出:

  1. var djb2Code = function (str) {
  2. var hash = 5381;
  3. for (i = 0; i < str.length; i++) {
  4. char = str.charCodeAt(i);
  5. hash = ((hash << 5) + hash) + char; /* hash * 33 + c */
  6. }
  7. return hash;
  8. }

接下来我们用js实现hashmap, hashmap是一种键值对的数据结构。意味着你可以通过key快速找到你所需要查找的值。我使用数组加上LinkedList来实现hashmap,这种方式也被称为解决hashcode冲突的分离链接法。hashmap通常具备以下几种方法:put,get,remove。put是写入和修改数据,在put数据时,首先获取key的hashcode,作为数组的索引。而数组索引对应的值则是一个linkedlist,并且linkedlist所存储的节点值,同时包含着所需存储的key和value。这样以便解决当hashcode重复冲突时,在链表中根据key名称来get查找值。 关于hashmap更多的原理,我推荐这篇文章 http://www.admin10000.com/document/3322.html

下面直接给出实现,其中使用到LinkedList数据结构的源码,在我的这篇分享当中:http://www.cnblogs.com/tdws/p/6033209.html

  1. var djb2Code = function (str) {
  2. var hash = 5381;
  3. for (i = 0; i < str.length; i++) {
  4. char = str.charCodeAt(i);
  5. hash = ((hash << 5) + hash) + char; /* hash * 33 + c */
  6. }
  7. return hash;
  8. }
  9.  
  10. function HashMap() {
  11. var map = [];
  12. var keyValPair = function (key, value) {
  13. this.key = key;
  14. this.value = value;
  15. }
  16. this.put = function (key, value) {
  17. var position = djb2Code(key);
  18. if (map[position] == undefined) {
  19. map[position] = new LinkedList();
  20. }
  21. map[position].append(new keyValPair(key, value));
  22. },
  23. this.get = function (key) {
  24. var position = djb2Code(key);
  25. if (map[position] != undefined) {
  26. var current = map[position].getHead();
  27. while (current.next) {
  28. if (current.element.key === key) { //严格判断
  29. return current.element.value;
  30. }
  31. current = current.next;
  32. }
  33. if (current.element.key === key) {//如果只有head节点,则不会进while. 还有尾节点,不会进while,这个判断必不可少
  34. return current.element.value;
  35. }
  36. }
  37. return undefined;
  38. },
  39. this.remove = function (key) {
  40. var position = djb2Code(key);
  41. if (map[position] != undefined) {
  42. var current = map[position].getHead();
  43. while (current.next) {
  44. if (current.element.key === key) {
  45. map[position].remove(current.element);
  46. if (map[position].isEmpty()) {
  47. map[position] == undefined;
  48. }
  49. return true;
  50. }
  51. current = current.next;
  52. }
  53. if (current.element.key === key) {
  54. map[position].remove(current.element);
  55. if (map[position].isEmpty()) {
  56. map[position] == undefined;
  57. }
  58. return true;
  59. }
  60. }
  61. }
  62. }
  63.  
  64. //链表
  65. function LinkedList() {
  66. var Node = function (element) {        //新元素构造
  67. this.element = element;
  68. this.next = null;
  69. };
  70. var length = 0;
  71. var head = null;
  72.  
  73. this.append = function (element) {
  74. var node = new Node(element);        //构造新的元素节点
  75. var current;
  76. if (head === null) {             //头节点为空时 当前结点作为头节点
  77. head = node;
  78. } else {
  79. current = head;
  80. while (current.next) {          //遍历,直到节点的next为null时停止循环,当前节点为尾节点
  81. current = current.next;
  82. }
  83. current.next = node;            //将尾节点指向新的元素,新元素作为尾节点
  84. }
  85. length++;                    //更新链表长度
  86. };
  87. this.removeAt = function (position) {
  88. if (position > -1 && position < length) {
  89. var current = head;
  90. var index = 0;
  91. var previous;
  92. if (position == 0) {
  93. head = current.next;
  94. } else {
  95. while (index++ < position) {
  96. previous = current;
  97. current = current.next;
  98. }
  99. previous.next = current.next;
  100. }
  101. length--;
  102. return current.element;
  103. } else {
  104. return null;
  105. }
  106. };
  107. this.insert = function (position, element) {
  108. if (position > -1 && position <= length) {        //校验边界
  109. var node = new Node(element);
  110. current = head;
  111. var index = 0;
  112. var previous;
  113. if (position == 0) {                    //作为头节点,将新节点的next指向原有的头节点。
  114. node.next = current;
  115. head = node;                        //新节点赋值给头节点
  116. } else {
  117. while (index++ < position) {
  118. previous = current;
  119. current = current.next;
  120. }                                //遍历结束得到当前position所在的current节点,和上一个节点
  121. previous.next = node;                    //上一个节点的next指向新节点 新节点指向当前结点,可以参照上图来看
  122. node.next = current;
  123. }
  124. length++;
  125. return true;
  126. } else {
  127. return false;
  128. }
  129.  
  130. };
  131. this.toString = function () {
  132. var current = head;
  133. var string = '';
  134. while (current) {
  135. string += ',' + current.element;
  136. current = current.next;
  137. }
  138. return string;
  139. };
  140. this.indexOf = function (element) {
  141. var current = head;
  142. var index = -1;
  143. while (current) {
  144. if (element === current.element) {            //从头节点开始遍历
  145. return index;
  146. }
  147. index++;
  148. current = current.next;
  149. }
  150. return -1;
  151. };
  152. this.getLength = function () {
  153. return length;
  154. };
  155. this.getHead = function () {
  156. return head;
  157. };
  158. this.isEmpty = function () {
  159. return length == 0;
  160. }
  161. }

参考文章:js获取hashcode  : http://www.cnblogs.com/pigtail/p/3342977.html

如果我的点滴分享对你有点滴帮助,欢迎点击下方红色按钮,我将长期输出分享。

学习Redis你必须了解的数据结构——HashMap实现的更多相关文章

  1. 学习Redis你必须了解的数据结构——JS实现集合和ECMA6集合

    集合类似于数组,但是集合中的元素是唯一的,没有重复值的.就像你学高中数学的概念一样,集合还可以做很多比如,并集,交集,差集的计算.在ECMA6之前,JavaScript没有提供原生的Set类,所以只能 ...

  2. 学习Redis你必须了解的数据结构——双向链表(JavaScript实现)

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文链接 http://www.cnblogs.com/tdws/ 下午分享了JavaScript实现单向链表,晚上就来补充下双向链表吧.对链表 ...

  3. 在微博微信场景下学习Redis数据结构

    Redis安装 下载地址:http://redis.io/download 安装步骤: 1.yum install gcc 2.wget http://download.redis.io/releas ...

  4. Redis源码分析-底层数据结构盘点

    前段时间翻看了Redis的源代码(C语言版本,Git地址:https://github.com/antirez/redis), 过了一遍Redis数据结构,包括SDS.ADList.dict.ints ...

  5. 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)

    redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...

  6. Redis(1)——5种基本数据结构

    一.Redis 简介 "Redis is an open source (BSD licensed), in-memory data structure store, used as a d ...

  7. 学习Redis好一阵了,我对它有了一些新的看法

    前言 本篇文章不是一篇具体的教程,我打算记录一下自己对Redis的一些思考.说来惭愧,我刚接触Redis的时候只是简单地使用了一下,背了一些面试题,就在简历上写下了Redis这个技能点. 我们能在网络 ...

  8. 你真的懂Redis的5种基本数据结构吗?

    摘要: 你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看. 本文分享自华为云社区<你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看>,作者:李子捌. 一 ...

  9. 学习Redis从这里开始

    本文主要内容 Redis与其他软件的相同之处和不同之处 Redis的用法 使用Python示例代码与Redis进行简单的互动 使用Redis解决实际问题 Redis是一个远程内存数据库,它不仅性能强劲 ...

随机推荐

  1. 使用C/C++写Python模块

    最近看开源项目时学习了一下用C/C++写python模块,顺便把学习进行一下总结,废话少说直接开始: 环境:windows.python2.78.VS2010或MingW 1 创建VC工程 (1) 打 ...

  2. 玩转spring boot——结合JPA入门

    参考官方例子:https://spring.io/guides/gs/accessing-data-jpa/ 接着上篇内容 一.小试牛刀 创建maven项目后,修改pom.xml文件 <proj ...

  3. C# 序列化与反序列化几种格式的转换

    这里介绍了几种方式之间的序列化与反序列化之间的转换 首先介绍的如何序列化,将object对象序列化常见的两种方式即string和xml对象; 第一种将object转换为string对象,这种比较简单没 ...

  4. 手动导入swift三方danielgindi/Charts到OC工程中教程

    1.到github网址上下载zip压缩包https://github.com/danielgindi/Charts 2.然后将解压后的文件夹整个拖到自己的工程文件夹下(很多教程只让拖xcodeproj ...

  5. MongoDB学习笔记五—查询上

    数据准备 { , "goods_name" : "KD876", "createTime" : ISODate("2016-12- ...

  6. Linux监控工具介绍系列——OSWatcher Black Box

      OSWatcher Balck Box简介 OSWatcher Black Box (oswbb)是Oracle开发.提供的一个小巧,但是实用.强大的系统工具,它可以用来抓取操作系统的性能指标,用 ...

  7. Linux C语言解析并显示.bmp格式图片

    /************************* *bmp.h文件 *************************/ #ifndef __BMP_H__ #define __BMP_H__ # ...

  8. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  9. 好好了解一下Cookie

    Cookie的诞生 由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的.Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用.比如判断用户是否是第一次访问网站.目前最新 ...

  10. 【初学者指南】在ASP.NET MVC 5中创建GridView

    介绍 在这篇文章中,我们将会学习如何在 ASP.NET MVC 中创建一个 gridview,就像 ASP.NET Web 表单中的 gridview 一样.服务器端和客户端有许多可用的第三方库,这些 ...