哈希表的定义
哈希表(Hash table,也叫散列表)是一种查找算法,与链表、树等算法不同的是,哈希表算法在查找时不需要进行一系列和关键字的比较操作。
哈希表算法希望能尽量做到不经过任何比较,通过一次存取就能得到所查找的数据元素,因而必 须要在数据元素的存储位置和它的关键字(可用key表示)之间建立一个确定的对应关系,使每个关键字和散列表中一个唯一的存储位置相对应。因此在查找时,只要根据这个对应关系找到给定 关键字在散列表中的位置即可。这种对应关系被称为哈希函数(可用H(key)表示)
哈希函数的构造方法
常用的哈希函数构造方法有:直接定址法、数字分析法、平方取中法、折叠法、随机数法和除留余数法。
(1)直接寻址法:取关键字或关键字的某个线性函数值作为散列地址,即 H(key) = key
或 H(key) = a * key + b
,其中 a 和 b 为常数(这种散列函数叫自身函数)。
(2)数字分析法:分析一组数据,比如某班学生的出生年月日时发现出生年月日的前几位数字大体相同,这样的话,冲突的几率会很大,但是发现年月日的后几位表示月份和具体日期的数字差别较大,如果用后几位构成散列地址,则冲突的几率会明显降低。因此数字分析法是找出数字的规律,尽可能利用这些数字构造冲突几率低的散列地址。
(3)平方取中法:先通过求关键字的平方值扩大相近的差别,然后根据表长度取中间的几位数作为散列函数值。又因为一个乘积的中间几位数和乘数的每一位都相关,所以由此产生的散列地址较为均匀。
(4)除余法:该方法是最为简单常用的一种方法。它是以表长 m 来除关键字,取其余数作为散列地址,即 H(key) = key % m
。该方法的关键是选取 m。选取的 m 应使得散列函数尽可能与关键字的各位相关。m 最好为素数。
(5)相乘取整法:该方法包括两个步骤,首先用关键字 key 乘上某个常数 A(0 < A < 1),并抽取出 key.A 的小数部分;然后用 m 乘以该小数后取整
处理冲突的方法:
-
开放定址法
-
链地址法
-
再哈希法
-
建立一个公共溢出区
Hashtable的基本操作
hashtable的初始容量是101
hashtable是线程安全的,put( ),remove( )方法等都有synchronized,所有效率不如hashmap。
public class Hashdemo {
public static void main(String[] args) {
Hashtable<Integer,String> hashtable=new Hashtable<>();
//存储键值对,键和值都不允许为空
hashtable.put(3,"张三");
hashtable.put(4,"李四");
hashtable.put(5,"王五");
hashtable.put(6,"赵六");
System.out.println(hashtable);
//判断哈希表是否包含给定关键字
System.out.println("key:2 :"+hashtable.containsKey(2));
System.out.println("key:3 :"+hashtable.containsKey(3));
//判断哈希表是否包含给定的对象
System.out.println("value:张三 :"+hashtable.contains("张三"));
System.out.println("value:小明 :"+hashtable.contains("小明"));
//根据关键字删除对象
hashtable.remove(4);
System.out.println("after remove"+hashtable);
//遍历哈希表
Iterator<Integer> iterator=hashtable.keySet().iterator();
while (iterator.hasNext()){
Integer key=iterator.next();
System.out.println(key+"--"+hashtable.get(key));
}
}
}