哈希表:
1:什么是哈希表。
哈希表是一种数据存储结构,它可以提供一些快速的查找和插入操作;也称作散列表。
是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录。
在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和结构中一个唯一的存储位置相对应。若关键字为k,则其值存放在f(k)的存储位置上。
对应关系f叫做哈希函数或者散列函数。
2:哈希过程中产生的冲突
把关键字通过哈希化转换成数组的下标,转换的过程给叫做哈希化,不同的关键字在转换后下表后可能指向了一个相同的地址,这种情况叫做冲突。
3:产生冲突后的解决办法(分为两大类):
a开放地址法:
通过系统的方式找系统的下一个空位,并且把我们的数据放进去或者取出来,不再用哈希函数得到的下标。
b链地址法:
创建一个存放链表的数组,数组内部直接存储数据,一旦发生冲突,数据项就直接找到数组下标所指的链表 ,在链表里边找相应的数据或存放数据;当元素的下标相同的时候,我们都把它存到一个下表下的链表当中。把数据项插入到链表,其他同样映射到位置,也是只需要加到链表中,不需要在原始的数据中寻找一些空位。
a-a 开放地址法再划分:线性探测,二次探测,再哈希法。
线性探测:对一个数字求余,因为我们的数可能非常的大,数组长度只有60.超出索引是不可以的,所以 我们用求余的方式找到数组下标,然后再对应找其他的数据。
二次探测就是增加探测的步长:先进行求余,产生第一次下标。然后加的步长是(1,4,9,16)找空位。
哈希表_再哈希法: 我们有一个哈希函数,可以再写第二个哈希化的函数,有要求:和第一个哈希化的函数不同;不能返回输出0(这样就没有步长了,这样就原地踏步了),也就是第一个哈希函数在调用的时候发生了冲突的时候,调用第二个哈希函数。
4 Java类集-Hashmap
HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。
HashMap数组每一个元素的初始值都是Null。
常使用的是两个方法:Get 和 Put。
5 :牛客笔经问题,讲一下hashmap,hashmap和ConcurrentHashMap有什么区别,hashmap的key可以为null吗?ConcurrentHashMap呢?
HashMap可以允许插入null key和null value
HashTable和ConcurrentHashMap都不可以插入null key和null value,源码中判断了null value的情况,null value就抛出空指针异常。
6:hashmap和ConcurrentHashMap有什么区别?(详细转自这里https://www.cnblogs.com/shan1393/p/8999458.html)
Hashmap本质是数组加链表。根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面。
ConcurrentHashMap:在hashMap的基础上,ConcurrentHashMap将数据分为多个segment(段),默认16个(concurrency level),然后每次操作对一个segment(段)加锁,避免多线程锁的几率,提高并发效率。
HashMap基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
值得注意的是HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap。
Map map = Collections.synchronizedMap(new HashMap());
HashMap底层是通过链表来解决hash冲突的;
HashMap其实就是一个Entry数组,Entry对象中包含了键和值,其中next也是一个Entry对象,它就是用来处理hash冲突的,形成一个链表;