Java数据结构-HashMap和HashSet

目录

一.集合框架图

 二.HashMap

1.整型存储

2.其他类型存储(引用类,字符串型)

3.哈希位置冲突

1.线性探测法:

2.二次探测法/平方探测法

3.开散列法/哈希桶

4.如何尽量避免哈希数的冲突 

注意:扩容的时候要重新哈希,也就是通过哈希函数重新哈希数据在进行存储。 

三.HashSet


一.集合框架图

Java数据结构-HashMap和HashSet_第1张图片

 二.HashMap

1.整型存储

HashMap实现自Map接口,从图中我们可以看出,实现Map接口的方法有三个,但在大多情况下,都是使用HashMap来实现,原因就是HashMap的增删查改时间复杂度都为O(1),这时我们未免会有疑问为什么HashMap的时间复杂度这么低?原因便是:

HashMap的存储是通过哈希函数来决定元素存储的位置的,比如说哈希函数为 k%3,而存储位置是一个大小为10array的数组,则1的存储位置为1%3=1,则.元素1就存储在array[1].

2.其他类型存储(引用类,字符串型)

在java中hashcode方法是Object类的native方法,返回值为int型,可以利用hashcode()方法来获取其他类型的哈希值再通过哈希函数进行存储。

3.哈希位置冲突

当进行hashmap的存储时,可能会有多个元素通过哈希函数后获得的哈希值相同,这时我们应该怎么处理?

哈希函数也叫作散列函数,当出现相同哈希数时需要我们来处理,具体处理方法如下。

Java数据结构-HashMap和HashSet_第2张图片

其中线性探测法就是当出现位置冲突时将元素放在冲突元素的

1.线性探测法:

线性探测法中函数是位置i的函数,这相当于当发生冲突的时候,逐个单元甚至回绕查询到一个空单元,也就是说数据都需要放置在这一个表格中,当发生冲突的时候就出发上面的机制,不过这样做,花费的时间是相当多的,这样单元会形成一些区域块,其结果称作为一次聚焦,也就是是说经过多次的查找才能找到一个空的单元:

    Hkey(x) = Hkey(n)+ i;

也就是当出现和n重复的hash值的时候,则需要逐个进行探测,因为可以回绕,所以可以只取一个方向继续查找空单元。不过分析一下可以看出,当表中元素多于一半的话,则需要查找的次数就更多了,这也就不再是一种好办法,耗费了大量的时间

2.二次探测法/平方探测法

二次探测法是消除线性探测法聚集问题的一种方法,流行的选择是f(i)= i^2.对于二次探测法,单元被填满,情况要比线性探测法更加严重,一旦表的大小超过一半,表的大小不是素数的时候,有可能在表被填充到一半之前就可能找不到空单元了,因此最多只有一半的空位置用来解决冲突问题。

3.开散列法/哈希桶

Java数据结构-HashMap和HashSet_第3张图片

4.如何尽量避免哈希数的冲突 

Java数据结构-HashMap和HashSet_第4张图片

其中负载因子为需要存储的数据数量除以数组容量

注意:扩容的时候要重新哈希,也就是通过哈希函数重新哈希数据在进行存储。 

三.HashSet

HashSet的底层是HashMap,只是HashSet只有key值没有val,具体实现可以参考HashMap。

最后记得三连^_^

 

你可能感兴趣的:(Java数据结构,从零基础学好算法与结构,java,数据结构,jvm)