- 4
- 0
- 约5.35千字
- 约 18页
- 2019-05-14 发布于未知
- 举报
PAGE
PAGE 2
数据存储方式和查询效率
内存数据的组织方式有很多,如:
数组:
采用开辟连续空间的方式存储。
优点:通过下标查询的时候可以计算出偏移量,立即定位到元素,查询速度很快。
缺点:
1:插入或删除元素时,往往需要移动元素位置,开销很大。
2:只有通过下标查询效率才高,如果需要通过元素内容查询,也需要遍历比较。(对于元素内容已经排序的数组,可以通过二分查找等方式提高效率,但避免不了比较)
思考:ArrayList是否通过这种方式存储,数组中存储的是什么,是不是对象引用?
链表
开辟非连续空间存储。
每一个元素额外存储下一个元素的地址(单向链表)。每一个元素额外存储下一个元素和上一个元素的地址(双向链表)
第一个元素的上一个元素地址为空,最后一个元素的下一个元素地址为空。
优点:插入或删除元素时,不需要移动其他元素位置,只需要修改链表下一个(上一个)元素地址即可,不需要连续的内存空间。
缺点:无论通过下标还是通过元素内容查找,都需要遍历比较。
采用哈希的方式。
为了让每次根据元素内容查询的时候不需要进行比较,必然需要查询时根据传入的内容直接找到存储地址,然后定位到存储地址一次性取出元素。而这个根据传入内容找存储地址的过程就是哈希算法,也叫散列算法,满足哈希查找的数据表也叫哈希表。这经常用在key-value存储的情况。
用公式表示就是:
存储地址=f(key)
f:哈希函数,key:查询的关键字
分为两步:
放入:将key-value表示的对象通过key做哈希算法算出一个地址,然后将value放到该地址。
2、查询,通过key查询时,用哈希算法算出一个地址,然后到该地址即可取出对应的value,不需要遍历比较。
ps:哈希算法不可逆,常用的有MD5、SHA-1等,存在碰撞问题。
java中hash表的应用
在java的Set、Map中这些容器中,需要快速根据key找到元素,如Set的contains方法,Map的get方法,都是通过key去查找。而这些容器确定元素唯一性都是通过回调元素的equals方法。
但这样每次都需要遍历所有元素去回调equals,效率很低。因此通常都用Hash的方式实现,如: HashSet、HashMap。
以HashSet为例(这里使用的是HashSet理想模型,并不是HashSet源码分析,实际上HashSet内部实现依赖了HashMap):
在HashSet中add元素时,它会回调元素的hashCode计算出位置,然后将元素放到该位置。查找元素时,它也会回调hashCode计算位置,到该位置上去找元素,如果找到,再回调equals看是否返回true,返回true就认为元素存在。HashMap的put和get也是同理,回调key的hashCode计算位置,存取value。
碰撞的处理:
HashSet存元素时,如果该位置已存在元素,则会将该位置的所有元素以单向链表的形式存放,取的时候遍历该链表,找到equals返回true的元素。HashMap也是同理。
所以最终确定元素唯一性的是equals方法,而hashCode方法是找元素位置。但如果hashCode不相同,即使equals返回ture也认为是不同元素,因为hashCode是找元素的第一步,没有找到就没机会调用equals了。
hashCode和equals
在Object中默认的hashCode返回的是根据对象的地址计算出的唯一数字,每个对象一个。
而默认的equals方法则是比较对象地址是否相等,也就是是否同一个对象。
这样Object的hashCode跟equals其实是等价的,只有同一个对象的hashCode才相等,并且equals返回true。
因此如果重写了equals方法,让不同对象也可能equals,则需要重写hashCode,保证equals返回ture时,hashCode也相等。
如果2个对象equals返回了true,而hashCode没有重写,则会使用的默认的Object提供的那个,也就是每个对象的hashCode都不同。而在HashSet、HashMap中会首先去比较hashCode,发现不同,则认为不是同一个元素,而实际上他们是equals的。
如:
虽然2个对象equals,但HashSet却把它们当成了不同元素,存了2个,因为它会先调用hashCode去找元素。
重写hashCode后的效果:
hashCode相同,equals也返回true,才认为是同一个元素。
但仅仅这样做还不够,因为hashCode即使不同,在Set或者HashMap内部的元素数组中也可能在同一个位置,因而需要在equals里面也加入对hashCode的判断
通常重写equals方法后,考虑重写hashCode都
原创力文档

文档评论(0)