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

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

 var djb2Code = function (str) {
var hash = 5381;
for (i = 0; i < str.length; i++) {
char = str.charCodeAt(i);
hash = ((hash << 5) + hash) + char; /* hash * 33 + c */
}
return hash;
}

接下来我们用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

   var djb2Code = function (str) {
var hash = 5381;
for (i = 0; i < str.length; i++) {
char = str.charCodeAt(i);
hash = ((hash << 5) + hash) + char; /* hash * 33 + c */
}
return hash;
} function HashMap() {
var map = [];
var keyValPair = function (key, value) {
this.key = key;
this.value = value;
}
this.put = function (key, value) {
var position = djb2Code(key);
if (map[position] == undefined) {
map[position] = new LinkedList();
}
map[position].append(new keyValPair(key, value));
},
this.get = function (key) {
var position = djb2Code(key);
if (map[position] != undefined) {
var current = map[position].getHead();
while (current.next) {
if (current.element.key === key) { //严格判断
return current.element.value;
}
current = current.next;
}
if (current.element.key === key) {//如果只有head节点,则不会进while. 还有尾节点,不会进while,这个判断必不可少
return current.element.value;
}
}
return undefined;
},
this.remove = function (key) {
var position = djb2Code(key);
if (map[position] != undefined) {
var current = map[position].getHead();
while (current.next) {
if (current.element.key === key) {
map[position].remove(current.element);
if (map[position].isEmpty()) {
map[position] == undefined;
}
return true;
}
current = current.next;
}
if (current.element.key === key) {
map[position].remove(current.element);
if (map[position].isEmpty()) {
map[position] == undefined;
}
return true;
}
}
}
} //链表
function LinkedList() {
var Node = function (element) {        //新元素构造
this.element = element;
this.next = null;
};
var length = 0;
var head = null; this.append = function (element) {
var node = new Node(element);        //构造新的元素节点
var current;
if (head === null) {             //头节点为空时 当前结点作为头节点
head = node;
} else {
current = head;
while (current.next) {          //遍历,直到节点的next为null时停止循环,当前节点为尾节点
current = current.next;
}
current.next = node;            //将尾节点指向新的元素,新元素作为尾节点
}
length++;                    //更新链表长度
};
this.removeAt = function (position) {
if (position > -1 && position < length) {
var current = head;
var index = 0;
var previous;
if (position == 0) {
head = current.next;
} else {
while (index++ < position) {
previous = current;
current = current.next;
}
previous.next = current.next;
}
length--;
return current.element;
} else {
return null;
}
};
this.insert = function (position, element) {
if (position > -1 && position <= length) {        //校验边界
var node = new Node(element);
current = head;
var index = 0;
var previous;
if (position == 0) {                    //作为头节点,将新节点的next指向原有的头节点。
node.next = current;
head = node;                        //新节点赋值给头节点
} else {
while (index++ < position) {
previous = current;
current = current.next;
}                                //遍历结束得到当前position所在的current节点,和上一个节点
previous.next = node;                    //上一个节点的next指向新节点 新节点指向当前结点,可以参照上图来看
node.next = current;
}
length++;
return true;
} else {
return false;
} };
this.toString = function () {
var current = head;
var string = '';
while (current) {
string += ',' + current.element;
current = current.next;
}
return string;
};
this.indexOf = function (element) {
var current = head;
var index = -1;
while (current) {
if (element === current.element) {            //从头节点开始遍历
return index;
}
index++;
current = current.next;
}
return -1;
};
this.getLength = function () {
return length;
};
this.getHead = function () {
return head;
};
this.isEmpty = function () {
return length == 0;
}
}

参考文章: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. ShenNiu.MVC管理系统

    本篇将要和大家分享的是一个简单的后台管理系统,这里先发个地址http://www.lovexins.com:8081/(登陆账号:youke,密码:123123:高级用户账号:gaoji,密码:123 ...

  2. netcore - MVC的ActionFilter的使用

    经过一周的时间没有分享文章了,主要是在使用.netcore做一个小的项目,项目面向大众用户的增删改查都做的差不多了,打算本周在云服务器上部署试试,很期待,也希望上线后大家多多支持:以上纯属个人废话,来 ...

  3. geotrellis使用(二十八)栅格数据色彩渲染(多波段真彩色)

    目录 前言 实现过程 总结 一.前言        上一篇文章介绍了如何使用Geotrellis渲染单波段的栅格数据,已然很是头疼,这几天不懈努力之后工作又进了一步,整清楚了如何使用Geotrelli ...

  4. 编译器开发系列--Ocelot语言5.表达式的有效性检查

    本篇将对"1=3""&5"这样无法求值的不正确的表达式进行检查. 将检查如下这些问题.●为无法赋值的表达式赋值(例:1 = 2 + 2)●使用非法的函数 ...

  5. 跟着老男孩教育学Python开发【第二篇】:Python基本数据类型

    运算符 设定:a=10,b=20 . 算数运算 2.比较运算 3.赋值运算 4.逻辑运算 5.成员运算 基本数据类型 1.数字 int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**3 ...

  6. Create a bridge using a tagged vlan (8021.q) interface

    SOLUTION VERIFIED April 27 2013 KB26727 Environment Red Hat Enterprise Linux 5 Red Hat Enterprise Li ...

  7. [jquery]jquery正则表达式验证(手机号、身份证号、中文名称)

    数字判断方法:isNaN()函数 test()方法 判断字符串中是否匹配到正则表达式内容,返回的是boolean值 ( true / false ) // 验证中文名称 function isChin ...

  8. .NET面试题系列[1] - .NET框架基础知识(1)

    很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...

  9. JqueryQrcode生成二维码不支持中文的解决办法

    JqueryQrcode.js有一个小小的缺点,就是默认不支持中文. 这跟js的机制有关系,jquery-qrcode这个库是采用 charCodeAt() 这个方式进行编码转换的, 而这个方法默认会 ...

  10. [开源]QuickSwitchSVNClient,快速完成SVN Switch的工具

    在实际的开发中,我们一般使用SVN工具进行源代码的管理.在实际的产品开发中,根据项目的一些定制要求,往往需要对某一些代码的修改,但是又不想影响主要的开发,这个时候需要对当前的主分支做一些分支处理(br ...