解决hash冲突的策略

在解决hash collision问题的时候发现resin4.0.7和resin4.0.26中临时保存form参数的Map实现类不同。4.0.7使用的java.util.HashMap,resin4.0.26使用的是自定义的com.caucho.util.HashMapImpl ,参考代码:

private V putImpl(K key, V value)
  {
    Object item = null;
    int hash = key.hashCode() & this._mask;
    int count = this._values.length;
    for (; count > 0; count--) {
      item = this._values[hash];
      if (item == null) {
        this._keys[hash] = key;
        this._values[hash] = value;
        this._size += 1;
        return null;
      }
      if (this._keys[hash].equals(key)) {
        this._values[hash] = value;
        return item;
      }
      hash = hash + 1 & this._mask;
    }
    throw new IllegalStateException();
  }

put操作的hash定位、collision解决方法和HashMap的put方式完全不同,当时很疑惑。。。

今天在看Trove的时候,才知道HashMapImpl使用的Open Addressing.Linear Probing方式来解决Hash Collision问题的。

关于Open Addressing的详细介绍:

http://hi.baidu.com/%B7%AB%C2%DE/blog/item/3e119f17c7151c32dd540193.html

http://www.ibm.com/developerworks/cn/java/j-perf09284.html

优缺点:

Trove 映射是采用开放选址而不是链接来实现的。在 Java 核心集合类中,多数映射都是使用链接实现,就是说如果多个键映射到表中的同一索引位置,则索引位置保存一个链表,其中存放映射到该位置的所有元素。开放选 址映射则假设表中邻近的位置存在没有使用的索引。如果目标位置已经被占用,映射实现就查看附近的几个位置找到一个没有使用的位置。这种方法不需要链表节 点,因此 Trove 映射和相同的核心集合类相比占用的内存更少。使用开放选址必须保证有足够的空闲索引,否则可能影响性能。(Trove 保持装载因子小于 0.5。)否则的话,开放选址的效率与链接基本相当,但多数情况下要好于后者。

开放选址的另一个优点是实现中不需要链表节点对象,链表节点需要靠链接来实现。为什么特别强调这一点呢?基本上每个 JVM 版本都会改进对象创建和无用单元回收的性能,但是较多的对象总会带来更多的开销。对于任何特定的问题,Java 编程中能够减少对象数量的解决方案通常都有更好的效率,这是一个标准的性能权衡问题,每个有经验的性能优化人员都知道。开放选址使用更少的对象来维护映射 结构,这意味着 Trove 映射在多数情况下比核心 Java 映射更有效,也更小。值得一提的是,最近越来越多的 Java 核心 Map 实现开始使用开放选址(比如 IdentityHashMap 类)。现有的其他核心 Java Map 实现最终也可能改为使用开放选址,虽然我们可能不那么关心,因为如果需要开放选址的实现,使用 Trove 就可以了。


其中IdentityHashMap.hash方法保证每次put操作,相同hashcodekey所被分配的地址是最后未被使用的位置,否则就需要resize


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值