繁体   English   中英

Java中HashMap的内部实现

[英]Internal implementation of HashMap in Java

我正在尝试在 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 中的 Hashfunction 将整数映射到某个索引? 程序也很好,我真的不需要代码。

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

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

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

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

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

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

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

Integer.hashCode(key)只返回key作为结果。 你可以写:

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

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

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

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

假设您的值将均匀分布,您可以使用除法的余数作为您的键的哈希值。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM