一:概述
一:为什么需要散列表
* 在我们的程序世界里,往往也需要在内存中存放这样一个“词典”,方便我们进行高效的查询和统计。
* 例如开发一个学生管理系统,需要有
* 通过输入学号快速查找对应学生的姓名的功能。
* 这里不必要每次都去查询数据库,而可以在内存中建立一个缓存表,这样做可以提高
* 查询效率。
* 学号 姓名
* 001121 张三
* 002123 李四
* 002931 王五
* 003278 赵六
*
* 再如我们需要统计一本英文书里面单词出现的频率,就需要遍历整本书的内容
* 把这些单词出现的次数记录在内存中。
* 单词 出现次数
* this 108
* and 56
* are 79
* by 46
* 因为这个需求,一个重要的数据结构诞生了,这个数据结构叫作散列表。
*
* 散列表i也叫作哈希表(hash table),这种数据结构提供了键(key)和值(value)的映射关系
* 只要给出一个key,就可以高效的查找它所匹配的Value,时间复杂度接近于O(1)。
*
二:哈希函数
* 在数组、链表、栈、队列中,数组的访问效率最高,对元素进行随机的访问
* 散列表在在本质上也是一个数组。
*
* 数组只能根据下标,像a[1]、a[2]、a[3]、a[4]、a[5]这样来访问,而散列表的Key则是以字符串
* 类型为主的。
* 例如以学生的学号作为Key,输入002123,查询到李四;或者以单词为Key,输入by,查询到数字
* 46.....
* 需要一个“中转站”,通过某种方式,把Key和数组下标进行转换。这个中转站就叫做哈希函数。
* 哈希函数的实现:
* 在不同的语言中,哈希函数的实现方式是不一样的。这里以Java常用集合HashMap为例。
* 来看一看哈希函数在Java中的实现。
*
* 在Java及大多数面向对象的语言中,每一个对象都有属于自己的hashcode,这个hashcode
* 是区分不同对象的重要标识。无论对象自身的类型是什么,它们的hashcode都是一个整型变量。
*
* 既然是一个整型变量,想要转换成数组的下标也就不难实现了。
* 最简单的实现方式就是按照数组的长度取模运算。
* 即:index = HashCode(Key) % Array.length
* 实际上,JDK(Java Development Kit,Java语言的软件开发工具包)中的哈希函数
* 并没有直接采取取模运算,而是利用了位运算的方式来优化性能。不过在这里姑且简单理解成
* 取模操作
*
* 通过哈希函数,我们可以把字符串或其他类型的Key,转换成数组的下标index。
* 如给出一个长度为8的数组,则当
* key = 001121时,
* index = HashCode("001121") % Array.length = 1420036703 %8 = 7
*而当key = this时,
* index = HashCode("this") % Array.length = 3559070 % 8 = 6 ;
*
标签:之散,Java,哈希,Key,初识,数组,列表,函数
From: https://blog.51cto.com/u_15912723/8082018