java之hashMap浅析


  谈到hashMap对象时,我想大部分的java开发人员头脑里面马上会蹦出这么一个植入骨髓的概念:

      键值对,即我们通常所说的key-value。

  没错,key-value的理解是正确的。倘若有人问你:key、value是如何存取的呢?

  通常我们的回答是:通过key值,直接获取返回的value值啊!

  倘若别人继续问你:如何通过key来获取一个value对象,key值又是如何生成以及存储的?

  我想好多人都无从回答了。

  下面我们简单分析下,map中的key和value的存取规则,看看和你之前的理解有何出入,写的不对的地方,希望各位大拿积极指点:

  下面看下hashMap实现的数据结构:


   在本文中,我们不关注java源码是怎么实现整个过程的,我们只关注它的实现原理。从上图中我们可以看到,图片的上方是一个很明显的数据类型(table[]),在数组的某些位置,会向下延伸出一些元素,它看起来是不是很像一个link链表呢?没错,它就是一个list链表。这就是hashtable的数据结构。说到这儿,可能有人迷糊了,hashTable不是键值对么,key值不是唯一的么,通过一个数组如何确认和定位呢?下面我详细介绍下:

    HashMap结构 = 一维数组(一维数组里面的元素可以是list链表)

大家可能对上面的数据结构犯晕了,没事,看我下面这段解释就清楚了。从事java开发的人都知道,hashMap跟放入key值的对象的hashcode方法相关。因为hashMap是通过hash码的方式进行数据的快速定位。而hash码是根据hashcode方法生成的。

假设我们有一个数组table[];

我们还有一个专门用来存放键值对的对象entity<key,value>;

Table数组里面存放的就是键值对对象引用entity<key,value>,那么为什么说haspmap取值速度很快呢,原因就在于前面提到的hash码,我们可以通过hash码来获取对于的entity<key,value>,既然entity<key,value>是放入table[]数组对象的,那么就不能想象:莫非hash码就是table[]数组的下标值。事实的确如此。让我们来分析如下一段代码,来分析下hashMap的存取过程:

  Map<String ,String> map = newHashMap<String,Sting>();

  map.put(“wang”,”男“);

我们假定hashMap中Table[]数组的初始长度是16,那么首先是创建:

Table[]tables = new Table[16];

然后将key-value值放入entity对象,entity对象中存在对key和value值的存取方法,然后将entity对象放入tables数组,可是该放入数组的什么位置呢,是按照顺序存储?还是随机存储?前面提到过,hashcode方法生成hash码就是我们对应的数组下标的位置,例如我们“wang“这个字符串如果生成的hash码为8,则对应我们的entity对象存储位置为:

tables[8] = entity1;

写到这儿,大家知道为什么hashMap取值的时候为什么这么快了吧,因为我在取值的时候先根据key值生成hash码8,直接去数组里面找索引为8的对象,没有数据的检索扫描,当然快了。

    不知道大家有没有这样的疑问,既然key值至少为了生成hash码,那为什么还要存储entity对象中呢?

这个其实在hashMap数据结构中其实已经有所体现了,大家看到数据对象其实可以是一个list链表集合。这是因为不同的对象、或者hashMap中定义的数组大小已经被沾满,那么hash码就是产生重复,就是出现如下情况:

 我们接着上面的例子:

  map.put(obj,”汽车对象“);

假如说obj是一个自定义的对象,二hashcode方法产生的hash码恰好也是8,那么,table数组将会是如下:

Listlist = new LinkedList();

list.add(entity1);//”wang”,”男”键值对

list.add(entity2);//obj和汽车对象

  Table[8] = list;

当我们通过map.get(obj)来获取汽车对象时,首先根据hash码8找到list,然后再遍历list里面的key值,通过key值的equals()方法进行比较,如果相等,则返回entity2里面的vale值,示意程序如下:

  Listlist = table[8];//通过hash码获取索引位置

For(Entity o :list){//遍历suolist

    o.key.equals(obj){//通过map.get里面的key同Entity里面的key进行比较

     return o.value;//返回vale值

}

}

如果map里面存储了大量的对象,那么也就是说hash码的重复值回越来越多,重复值越多,数组里面的linklist元素越多,需要经过大量的遍历和判断,程序性能就是越来越差。下一次我将把我对hashMap的性能优化的理解进行总结。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值