映射表(二)

上一篇从数据结构方面简单介绍了映射表,这一篇介绍java对这一数据结构的实现,java提供了种类繁多的map,主要从两个方面一个是hash的方式(HashMap),另外一种是树形结构(TreeMap),两者都实现了map接口.
谈到HashMap就不得不说HashTable,那么它们两个有什么不同呢?[java的面试或笔试题出现几率比较高的一题],HashTable是java对映射表的最早实现,它不但实现了映射表而且是线程安全的,不过它控制线程安全的方式比较直接,只是对该同步的方法进行了同步(使用synchronize关键字) ,也正是因为这样,所以导致HashTable的速度不如HashMap,这是最直接的解释,但实际上HashMap对HashTable作了很多细节上的改进,比如HashTable只是简单的使用要存入映射表的元素
(Key,value)的中的Key的HashCode。而HashMap对Key进行了再散列,这样严格确保了HahsCode的唯一性,同时它的Hash函数要比HashTable高效只是简单的用了一句

// h is hashcode
// length is length of the map
return h & (length-1);

恰好这种计算映射表中元素位置的方法也于python一样(不知道是谁学谁的 :)),再比如他在确定元素的Key是否相同时也使用了比较严格的比较方式,等等,但是它们两个处理冲突的方式是一致的,使用的都是链地址法,而这种方法适合于经常进行插入和删除的情况。所以建议使用HashMap,但如果我们需要同步的Map该怎么办?有很多方法,但是jdk1.5为我们提供一种更高效的方式,直接使用ConcurrentHashMap类,因此如果是基于jdk1.5以上的开发,请尽量使用ConcurrentHahMap。[关于这个类因为牵扯到了线程方面的问题,想单独讨论]。
接下来讨论一下HashMap的装填因子,和容量,还有初始的大小,如果不去显示的指定这些,那么HashMap默认的装填因子是0.75,初始化大小为16,因此在一个HashMap最初的容量是16 * 0.75 = 12,如果我们使用0.75这个装填因子,那么Map的大小必须是2的n次幂,一个HashMap的大小是2的30次幂(很大哦,以至于java的实现都没使用字面量,而是使用了一个移位运算
1 << 30).
基于HashMap,又派生了LinkedHashMap还有IdentityHashMap,对于IdentityHashMap,键的散列码不是key的HashCode,而是Key的内存地址,因此,它使用==比较两个对象,而不是equals方法。对于LinkedHashMap,它通过使用双向链表,使得插入映射表中的元素,在表面上具有了按插入顺序的顺序,groovy的map使用的就是这个类。
其它的还有WeakHashMap和EnumMap(由于篇幅,下次讨论)
对于TreeMap,它的实现是基于搜索树的数据结构,因此它是允许对映射表的元素进行排序的。[由于这又牵扯到了数据结构,在此只是简单的提一下],因此如果没有对元素顺序的特殊要求,请使用HashMap,因为在存储和查询它的效率都要优于树结构。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值