Myhashmap扩展了hashmap并覆盖了hash函数

时间:2017-01-13 11:50:18

标签: java algorithm hashmap

如果我有一个类myhashmap,它扩展了hashmap,然后我重写函数hash以返回一个常量,那么我的地图中的插入和查找是如何受到影响的?

2 个答案:

答案 0 :(得分:2)

完全没有。您可以在Myhashmap中覆盖的唯一内容是hashCode()本身的Myhashmap。这不会影响Myhashmap if的性能。另一方面,HashSet<Myhashmap>Map<Myhashmap, ?>会表现得非常糟糕。

要理解这一点,您必须了解HashSet(或HashMap的基本功能,但原理是相同的)。两者都是通过根据哈希值将Object分配到存储桶中来实现的:

List<T>[] buckets = new List<>[bucketnum];

void add(T t){
    List<T> l = buckets[t.hashCode() % buckets.length];
    if(!l.contains(t))
        l.add(t);
}

虽然这个实现过于简单并且不应该在实际代码中使用,但它清楚地表明了一件事:HashSet很快,因为它使用了桶。但是,使hashCode() - 方法返回常量将导致HashSet,其中所有值都插入到单个存储桶中。换句话说:只需抛弃HashSet并使用List,因为在最好的情况下运行时根本不会发生变化,或者甚至可能更糟糕,因为{{1}与HashSet/-Map相比,引入了开销。例如。如果达到某个负载因子,List会增加桶数,这需要额外的资源。

编辑:
这有点深入,虽然它有趣,因为它显示了HashSet/-Map的不同实现,但它没有必要理解,因为它只是一个扩展以上对哈希数据结构的介绍应该被视为脚注。实际上还有另一种选择:Collision resolution。在这种情况下,不存在HashSet/-Map来存储共享某个哈希桶的对象。相反,算法以特定模式搜索可用桶。这可能是线性的,二次的等等。

E.g:

List

此代码使用线性碰撞策略来处理碰撞哈希(两个对象T[] buckets; boolean add(T t){ int index = t.hashCode() % bucketnum; for(int i = 0; i < bucketnum; i++){ if(buckets[(i + index) % bucketnum] == null){ buckets[(i + index) % bucketnum] = t; return true; } } return false; } a,这样b)。虽然此实现显示了一些不同的行为并且需要不同的负载因子,但仍然需要适当的散列函数,否则性能将比使用桶列表方法更差。

答案 1 :(得分:0)

在哈希函数中返回常量值没有意义。如果这样做,hashMap将变成简单的链表。

tab[i = (n - 1) & hash]这里n是地图的大小。 如果你的哈希值是常量,那么它的结果总是不变的,而get / put函数需要花费O(N)时间。