散列的数据结构:目的在于快速根据一个对象查找另外一个对象,及保存键值对。

平时在Java中使用散列的数据结构的容器有:

HashSet HashMap LinkedHashSet  LinkedHashMap

 

散列数据结构实现快速查询的原理:查询速度的瓶颈就是键的查询

散列的目的就在于提高查询速度。

以Map为例子   (存储一组数据的最快的数据结构就是数组)

散列数据结构将键值信息是保存在一个的数组内,每个数组位置放置一个List集合,键值就放于此。

所以数组并不直接保存键值本身,而是保存装键值的List。至于键值具体要放置到哪一个List中,则

通过键值对象的生成一个数字,以此数字作为保存键值集合的数组下标,而这个数字就是散列码(通过对象的hashCode()产生的)。

在把键值放入List的时候,校验键值是否重复 则是通过键值对象的equals()方法去比较的。

 

为什么要求实体Bean不仅要重写equals() 还要重写hashCode()

通过get()方法去获取

首先通过键值对象的hashCode()生成散列,确定键值所在数组的位置,然后遍历List通过equals()方法去匹配

这就是为什么要求实体Bean不仅要重写equals() 还要重写hashCode()

如下重写

return getId().hashCode();

 

为什么 数组中再放一个List,而不是一个键值对应一个数组位置呢?

这是因为 我们所用的上述容器,都是可以扩容的,而数组的不能长度是一定的。这就会导致键值的个数大于数组的长度。为解决这个问题不同的键值可以产生相同的散列码。

 

为什么String类型不需要重写以上两个方法呢?

这是因为Java对String类在内存存储时进行了优化。

比如String st1 = new String("kk") 

    String st2 = new String("kk")

在建立String对象时会先在内存中查找是否有相同字符串,如果有则不再新建而是直接存在的字符串的引用。所以st1 st2两个是指向的同一个引用。而父类的equals() hashCode()都是根据对象的引用地址来计算和比较的。所有String类型就不必重写这两个方法