在上章节中已经介绍了通过红黑树实现键值对数组的查询操作,复杂度是logN。

有没有性能更好的算法呢?答案是有。

基本想法就是计算keyword的哈希值,再通过哈希值直接获取相应的键值。

这样的方法的须要解决的问题是:

  • 怎样计算哈希值

  • 怎样解决哈系冲突

哈希函数

目标

依据对象中的成员变量的值,依照一定的规则计算出一个整数。这个整数就是哈希值。

哈希值最重要的两个属性是:

  • 假设a.equals(b),那么a.hashCode() == b.hashCode()

  • 理想状况下。假设!a.equals(b),那么a.hashCode() != b.hashCode()

Java中的hash

Java中的Object对象中已经包括了hashCode函数,因为全部的对象都继承自Object,因此全部的对象都有hashCode函数。该函数能返回一个整数。代表这个实例的哈希值。

Java中Integer类型的hashCode代码例如以下:

public int hashCode() {return value;
}

Double类型的hashCode代码例如以下:

public int hashCode() {long bits = doubleToLongBits(value);return (int)(bits ^ (bits >>> 32));
}

String类型的hashCode代码例如以下:

public int hashCode() {int off = offset;char val[] = value;int len = count;int h = 0;for(int i = 0; i < len; i++) {h = 31*h + val[off++];}return h;
}

这样的计算哈系的办法称之为Hornor哈希法。这样的方法是一种很简单的哈系算法。构造哈系冲突是很easy的。在2011年11月,有人发现Java的HashMap存在漏洞easy让黑客实现Dos攻击,它的原理就是构造大量的哈系冲突让HashMap的复杂度从1变为N,占用大量的CPU资源,BUG的具体信息戳这里:https://bugzilla.redhat.com/show_bug.cgi?

id=CVE-2012-2739

因为String是不可变的类型,因此能够对hashCode进行缓存。

自己定义类型的hash计算

public class Student {private int number;private String name;private String classname;public int hashCode() {int hash = 17;hash = hash*31 + name.hashCode();classname = hash*31 + classname.hashCode();}
}

其原理就是依照Hornor哈系法将各个成员变量的哈希值连接在一起。

哈希的取模操作

取模操作就是希望让哈系值能在0 ~ M-1范围内,便于通过它来訪问数组。

第一种方法的代码例如以下:

private int hash(Key key) {return key.hashCode() % M;
}

这段代码是错的。

这样的方法使用了取余数的操作,对于负数就会产生错误。

另外一种方法的代码例如以下:

private int hash(Key key) {return Math.abs(key.hashCode()) % M;
}

这段代码中有BUG。这样的方法在hashCode为负的0x80000000时会错误发生。由于它不能取相反数。

第三种方法的代码例如以下:

private int hash(Key key) {return (key.hashCode() & 0x7fffffff) % M;
}

这样的方法才是正确的。

算法6-1:哈希函数相关推荐

  1. 相似图像搜索的哈希算法思想及实现(差值哈希算法和均值哈希算法)

    图像相似度比较哈希算法: 什么是哈希(Hash)? • 散列函数(或散列算法,又称哈希函数,英语:Hash Function)是一种从任何一种数据中创建小 的数字"指纹"的方法.散 ...

  2. “中国诺贝尔奖”首位女得主王小云:哈希函数是区块链的起源性技术,区块链已扩展到供应链金融等多领域...

    "哈希函数.数字签名算法.加密算法是密码学三类基础算法,其中哈希函数是起源性技术." 本文旨在传递更多市场信息,不构成任何投资建议. 火星财经APP(微信:hxcj24h)一线报道 ...

  3. 1.1 密码学哈希函数

    我们需要理解的第一个密码学的基础知识是密码学哈希函数,哈希函数是一个数学函数,具有以下三个特性: ● 其输入可为任意大小的字符串. ● 它产生固定大小的输出.为使本章讨论更具体,我们假设输出值大小为2 ...

  4. 她破解哈希函数算法:坚持10年做一件事一定能做成

    今年9月7日,2019未来科学大奖揭晓,这项设立4年的大奖迎来首位女性得主--密码学家王小云.在信息时代,金融服务.网络安全等背后都离不开密码系统的"护航".在大众眼中,密码带着神 ...

  5. 高级数据结构与算法 | 哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶

    文章目录 哈希 哈希函数 常见的哈希函数 字符串哈希函数 哈希冲突 闭散列的解决方法 开散列的解决方法 负载因子以及增容 对于闭散列 对于开散列结构 具体实现 哈希表(闭散列) 插入 查找 删除 完整 ...

  6. 哈希算法(哈希函数)的基本使用

    哈希算法(哈希函数)的基本使用 什么是哈希? 哈希的原理和特点 数组与哈希表 哈希函数 哈希函数的冲突与碰撞 哈希算法 哈希的应用 什么是哈希? 如果我们需要誊抄一本新华字典,那么有什么方法呢?比如当 ...

  7. [算法入门笔记] 9. 哈希表与哈希函数

    文章目录 1. 哈希表与哈希函数的实现 2. 设计RandomPool结构 3. bitmap 3.1 概述 3.2 常用操作 3.2.1 存储数据 3.2.2 添加操作 3.2.3 删除操作 3.2 ...

  8. 数据结构与算法五:哈希表-哈希函数设计原则-哈希冲突解决方案

    一.哈希表的定义: 二.哈希表举例: 哈希函数就是映射关系 三.哈希表应用举例: Leetcode上第387题: 思路:通过s.charAt(i)-'a'将字符串中的字符映射成hash表,出现一次,在 ...

  9. 字符串哈希函数算法的PHP 实现

    恩...或许还有朋友不清楚字符串的哈希函数到底有什么用,这个用处呢,就是将字符串转换成数字,同时让所得数字尽量平均的分布在容器中,换句话说就是让字符串得到相同数字这种情况尽可能少的出现.当然咯...容 ...

最新文章

  1. 干货分享|安全测试起航之旅
  2. 深入理解Linux内核-内存寻址
  3. jquery同步请求
  4. java难点在哪里_java的难点在哪?
  5. windows启动minio bat脚本编写示例
  6. PHP5.2至5.6的新增功能详解
  7. Intellj(IDEA) warning no artifacts configured
  8. java中怎么制作单选框_java代码swing编程 制作一个单选按钮的Frame
  9. Bing每日壁纸API分享
  10. calibration trl 设计_校准:怎样设计和验证TRL校准件以及TRL校准的具体过程
  11. IPv6 to IPv4过渡技术——手工隧道和GRE隧道配置实例
  12. centos 安装jenkins
  13. Studio 3T 使用教程 mogodb
  14. Ubuntu14.04/16.04安装Dukto
  15. 怎么把ppt弄成链接的形式_ppt链接excle表格:如何在ppt中超级链接到指定的excel工作表...
  16. Arithmetic circuit
  17. 图解电动汽车:电动汽车充电接口
  18. Spring IOC和DI 的学习资料(附带大师英文文章)
  19. 涨姿势 - 了解各种常见的CO(CIO、CEO、CFO...)
  20. linux双屏原理,Linux下双屏显示设置

热门文章

  1. JBoss 系列九十六:JBoss MSC - 简介及一个简单演示样例
  2. android源代码
  3. asp.net 研发,测试,或现网....非本机环境采用附加进程的方式在本地调试
  4. DISCUZ 使用 JQ做效果导致DIY失效的解决办法
  5. keras_14_初始化Initializers
  6. [Python设计模式] 第8章 学习雷锋好榜样——工厂方法模式
  7. Ansible的Inventory管理
  8. [转载]Unix 高手的另外 10 个习惯
  9. Jsonp 跨域请求实例
  10. Convert(varchar(8),Getdate(),108) 什么意思