目录
一.集合框架图
二.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的存储时,可能会有多个元素通过哈希函数后获得的哈希值相同,这时我们应该怎么处理?
哈希函数也叫作散列函数,当出现相同哈希数时需要我们来处理,具体处理方法如下。
其中线性探测法就是当出现位置冲突时将元素放在冲突元素的
1.线性探测法:
线性探测法中函数是位置i的函数,这相当于当发生冲突的时候,逐个单元甚至回绕查询到一个空单元,也就是说数据都需要放置在这一个表格中,当发生冲突的时候就出发上面的机制,不过这样做,花费的时间是相当多的,这样单元会形成一些区域块,其结果称作为一次聚焦,也就是是说经过多次的查找才能找到一个空的单元:
Hkey(x) = Hkey(n)+ i;
也就是当出现和n重复的hash值的时候,则需要逐个进行探测,因为可以回绕,所以可以只取一个方向继续查找空单元。不过分析一下可以看出,当表中元素多于一半的话,则需要查找的次数就更多了,这也就不再是一种好办法,耗费了大量的时间
2.二次探测法/平方探测法
二次探测法是消除线性探测法聚集问题的一种方法,流行的选择是f(i)= i^2.对于二次探测法,单元被填满,情况要比线性探测法更加严重,一旦表的大小超过一半,表的大小不是素数的时候,有可能在表被填充到一半之前就可能找不到空单元了,因此最多只有一半的空位置用来解决冲突问题。
3.开散列法/哈希桶
4.如何尽量避免哈希数的冲突
其中负载因子为需要存储的数据数量除以数组容量
注意:扩容的时候要重新哈希,也就是通过哈希函数重新哈希数据在进行存储。
三.HashSet
HashSet的底层是HashMap,只是HashSet只有key值没有val,具体实现可以参考HashMap。
最后记得三连^_^