用Java编写哈希函数

时间:2018-11-12 14:26:14

标签: java hashmap hash-function

我正在尝试用Java创建HashMap()的数据结构。 HashMap必须最多进行N = 1000个操作,并且键仅是正整数。我所做的是:

class MyHashMap {
        final ListNode[] nodes = new ListNode[1000];
        // "put", "get" and "remove" methods which take
        // collisions into account using "chaining".
}

要确定新的键值对在nodes中的位置,我总是需要计算一个索引。我使用的功能是:

 public int getIndex(int key) { return Integer.hashCode(key) % nodes.length;}

返回0nodes.length之间的整数。但是,如何在不使用Integer.hashMap(key)的情况下用Java自己编写一个将整数映射到某个索引的哈希函数呢? 程序也很好,我真的不需要代码。

3 个答案:

答案 0 :(得分:2)

散列int值的一种简单策略是乘以一个大常数。如果不使用常数,则根据密钥分配的不同,碰撞率可能会非常差。仍然有可能获得较差的密钥分配,但是对于真实数据则不太可能。

注意:除非您知道密钥不能为负,否则应使用Math.abs来确保它为非负。

static final int K = 0x7A646E4D; // some large prime.

public int getIndex(int key) { 
    return Math.abs(key * K % nodes.length);
}

一个更快的解决方案是放弃使用%的乘法和移位。例如

public int getIndex(int key) { 
    return (int) ((key * K & 0xFFFF_FFFFL) * nodes.length >>> 32);
}

这是将key * K转换为分数,并且比使用%更快

答案 1 :(得分:0)

Integer.hashCode(key)仅返回key作为结果。您可以这样写:

public int getIndex(int key) { 
    return key % nodes.length;
}

这样,您就不会使用Integer.hashCode(key)

如果您没有看到类ListNode,则您的MyHashMap结构可能会出现问题,因为您要为同一数组元素设置许多元素。例如,密钥31003将保存在同一节点元素中。您必须将MyHashMap设计为列表列表(或列表数组或类似内容)。

答案 2 :(得分:0)

首先,hash是唯一的或很少重复的值。

假设您的值将平均分配,则可以将除法的其余部分用作键的哈希值。

public int get(int key) {
    return (-1 ^ key) % nodes.length;
}