在JVM5与JVM6中运行相同的程序时,HashMap中项目的顺序不同 [英] Order of items in a HashMap differ when the same program is run in JVM5 vs JVM6

查看:91
本文介绍了在JVM5与JVM6中运行相同的程序时,HashMap中项目的顺序不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序显示行中的一组对象,一个对象=一行。这些对象存储在一个HashMap中。行的顺序不会影响应用程序的功能(这就是为什么使用HashMap而不是可排序的集合)。



然而我注意到相同的应用程序在使用两个不同版本的Java虚拟机运行时运行不同。该应用程序使用JDK 5编译,可以使用Java 5或Java 6运行时运行,没有任何功能差异。



有问题的对象覆盖 java.lang。 Object#hashCode() ,并且很明显注意遵循Java API中指定的协议。事实证明这一点,即它们在应用程序的每次运行中(在同一个Java运行库中)总是以相同的顺序出现。



为了好奇,为什么选择Java运行时会影响命令吗?

解决方案 >可以做改变。最有可能的是这个私有方法(这是JDK 1.6.0_16):

  / ** 
*应用一个给定的hashCode的补充散列函数,
*防止低质量的散列函数。这是至关重要的
*,因为HashMap使用两个长度的哈希表,所以
*会碰到hashCodes的冲突,而这些hashCodes在低位中不会有
*的差异。注意:空键总是映射到散列0,因此索引为0.
* /
static int hash(int h){
//此函数确保只有
//每个比特位置的常数倍数有一个有界的
//碰撞次数(默认加载因子大约为8)。 (h>>> 20)^(h>> 12);
return h ^(h>> 7)^(h>> 4);
}

供参考,JDK 1.5.0_06中的模拟器是:

  / ** 
*返回指定对象的哈希值。除了
*对象自己的hashCode之外,该方法还应用了补充
*散列函数,该函数可防范质量差的散列函数。
*这很关键,因为HashMap使用两个长度为
*的散列表的幂。< p>
*
*此函数中的移位距离被选为整个四维搜索空间自动搜索的结果
*。
* /
static int hash(Object x){
int h = x.hashCode();

h + =〜(h <9);
h ^ =(h>>> 14);
h + =(h <4);
h ^ =(h>>> 10);
返回h;
}


I have an application which displays a collection of objects in rows, one object = one row. The objects are stored in a HashMap. The order of the rows does not affect the functionality of the application (that is why a HashMap was used instead of a sortable collection).

However I have noticed that the same application runs differently when run using two different versions of the Java Virtual Machine. The application is compiled using JDK 5, and can be run using either Java 5 or Java 6 runtimes, without any functional difference.

The object in question overrides java.lang.Object#hashCode() and obviously care has been taken to follow the contract specified in the Java API. This is evidenced by the fact that they always appear in the same order in every run of the application (in the same Java runtime).

For curiosity's sake, why does the choice of Java runtime affect the order?

解决方案

The implementation details of HashMap can and do change. Most likely this package private method did (this is from JDK 1.6.0_16):

/**
 * Applies a supplemental hash function to a given hashCode, which
 * defends against poor quality hash functions.  This is critical
 * because HashMap uses power-of-two length hash tables, that
 * otherwise encounter collisions for hashCodes that do not differ
 * in lower bits. Note: Null keys always map to hash 0, thus index 0.
 */
static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}

For reference, the analogue in JDK 1.5.0_06 is:

/**
 * Returns a hash value for the specified object.  In addition to 
 * the object's own hashCode, this method applies a "supplemental
 * hash function," which defends against poor quality hash functions.
 * This is critical because HashMap uses power-of two length 
 * hash tables.<p>
 *
 * The shift distances in this function were chosen as the result
 * of an automated search over the entire four-dimensional search space.
 */
static int hash(Object x) {
    int h = x.hashCode();

    h += ~(h << 9);
    h ^=  (h >>> 14);
    h +=  (h << 4);
    h ^=  (h >>> 10);
    return h;
}

这篇关于在JVM5与JVM6中运行相同的程序时,HashMap中项目的顺序不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆