Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中使用整数作为HashMap的键_Java_Collections - Fatal编程技术网

在Java中使用整数作为HashMap的键

在Java中使用整数作为HashMap的键,java,collections,Java,Collections,最近,我正在寻找Java API中的hashCode()方法的良好实现,并查看了Integer源代码。没有料到,但是hashCode()只返回返回返回的int值 public final class Integer ... { private final int value; ... public int hashCode() { return Integer.hashCode(value); } public static int hashCode(in

最近,我正在寻找Java API中的
hashCode()
方法的良好实现,并查看了
Integer
源代码。没有料到,但是
hashCode()
只返回返回返回的
int

public final class Integer ... {
private final int value;
...
    public int hashCode() {
        return Integer.hashCode(value);
    }
    public static int hashCode(int value) {
        return value;
    }
这真的很奇怪,因为有很多论文、页面和软件包专门讨论这个问题——如何设计好散列函数来分配值

最后我得出了这样的结论:


Integer
HashMap
一起使用时,是键的最差数据类型候选项,因为所有连续键都将放在一个存储箱中。就像上面的例子一样

Map<Integer, String> map = HashMap<>();

for (int i = 1; i < 10; i++) {
    map.put(Integer.valueOf(i), "string" + i);
}
Map-Map=HashMap();
对于(int i=1;i<10;i++){
map.put(Integer.valueOf(i),“string”+i);
}
有两个问题,我在谷歌搜索时没有找到答案:

  • 关于
    Integer
    数据类型,我的结论正确吗
  • 如果这是真的,为什么在使用幂运算、素数和二进制移位时,
    Integer的hashCode()
    方法不以某种巧妙的方式实现呢

  • 当与HashMap一起使用时,Integer是键的最差候选数据类型,因为所有连续键都将放在一个容器中

    不,那句话是错的

    事实上,
    Integer
    hashCode()
    的实现是最好的实现。它将每个
    Integer
    值映射到一个唯一的
    hashCode
    值,从而减少不同键映射到同一个bucket中的可能性

    有时一个简单的实现是最好的

    Object
    类中
    hashCode()
    的Javadoc:

    根据java.lang.Object.equals(java.lang.Object)方法,如果两个对象不相等,则对这两个对象中的每一个调用hashCode方法都必须产生不同的整数结果,这不是必需的但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能

    Integer
    是为数不多的几个类之一,这些类实际上保证不相等的对象将具有与以下对象不同的
    hashCode()

    hashCode的总合同为:

    每当在Java应用程序的执行过程中对同一对象多次调用hashCode时,hashCode方法必须一致 如果在equals中未使用任何信息,则返回相同的整数 修改对象上的比较。这个整数不需要保留 从应用程序的一次执行到另一次执行的一致性 同样的应用

    -->
    Integer#hashCode
    实现了这一点

    如果根据equals(Object)方法,两个对象相等,则必须对这两个对象中的每一个调用hashCode方法 生成相同的整数结果

    -->
    Integer#hashCode
    也实现了这一点

    根据equals(java.lang.Object)方法,如果两个对象不相等,则不需要调用hashCode方法 在两个对象中的每个对象上,必须生成不同的整数结果。 但是,程序员应该知道,生成不同的 不相等对象的整数结果可能会提高 哈希表


    -->
    Integer#hashCode
    最大限度地实现了这一点,即两个不相等的
    Integer
    s将永远不会具有相同的哈希代码

    除了@Eran的答案之外,Java的
    HashMap
    还具有防止“坏散列函数”(Integer.hashCode()不是,但仍然是)的功能


    因此,使用HashMap时,整数的“简单散列”实际上会有点不同。

    是的,您的结论是正确的“所有连续键都将放在一个箱子中”-不,一点也不正确。你似乎对炸薯条的工作原理有一些误解。实际上我没有找到答案。我终于从putVal()获得了这种代码的宁静
    if((p=tab[I=(n-1)&hash])==null)
    /**
     * Computes key.hashCode() and spreads (XORs) higher bits of hash
     * to lower.  Because the table uses power-of-two masking, sets of
     * hashes that vary only in bits above the current mask will
     * always collide. (Among known examples are sets of Float keys
     * holding consecutive whole numbers in small tables.)  So we
     * apply a transform that spreads the impact of higher bits
     * downward. There is a tradeoff between speed, utility, and
     * quality of bit-spreading. Because many common sets of hashes
     * are already reasonably distributed (so don't benefit from
     * spreading), and because we use trees to handle large sets of
     * collisions in bins, we just XOR some shifted bits in the
     * cheapest possible way to reduce systematic lossage, as well as
     * to incorporate impact of the highest bits that would otherwise
     * never be used in index calculations because of table bounds.
     */
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }