我经常hashCode()使用IntelliJ IDEA 自动生成类的方法,通常该方法采用以下形式:
result = 31 * result + ...
Run Code Online (Sandbox Code Playgroud)
我的问题是乘以31的目的是什么?我知道这是一个素数,但为什么选择31?此外,如果hashCode()为特别小/大的数据集实现a ,人们会以不同的方式处理这个问题吗?
两个Object实例是否可能具有相同的哈希码?
理论上,对象的哈希码是从其内存地址派生的,因此所有哈希码都应该是唯一的,但是如果在GC期间移动对象会怎样?
鉴于.Net能够通过IntPtr检测位数(通过反射器查看大量标记不安全,但是 - 耻辱)我一直认为GetHashCode返回int可能是短视的.
我知道最终使用良好的哈希算法,Int32提供的数十亿个排列绝对足够,但即便如此,可能的哈希集合越窄,散列密钥查找速度越慢,因为需要更多的线性搜索.
同样 - 我是唯一一个发现这个有趣的人:
struct Int64{
public override int GetHashCode()
{
return (((int) this) ^ ((int) (this >> 0x20)));
}
}
Run Code Online (Sandbox Code Playgroud)
虽然Int32只是返回this.
如果由于性能问题导致IntPtr不可能,那么实现IEquatable等的IHashCode可能更好吗?
随着我们的平台在内存容量,磁盘大小等方面变得越来越大,当然32位哈希足够的日子可能会被编号?
或者仅仅是通过接口抽象散列或根据平台调整散列大小所涉及的开销超过任何潜在性能优势的情况?
请考虑以下代码:
struct Vec2 : IEquatable<Vec2>
{
double X,Y;
public bool Equals(Vec2 other)
{
return X.Equals(other.X) && Y.Equals(other.Y);
}
public override bool Equals(object obj)
{
if (obj is Vec2)
{
return Equals((Vec2)obj);
}
return false;
}
// this will return the same value when X, Y are swapped
public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
除了比较双精度的平等对话(这只是演示代码)之外,我关注的是当X,Y值被交换时存在哈希冲突.例如:
Vec2 A = new Vec2() { X=1, Y=5 };
Vec2 B = new Vec2() { X=5, Y=1 };
bool test1 = …Run Code Online (Sandbox Code Playgroud) 我想知道如何在Java中散列一个double?我已经散列了其他原始数据和对象.我以为我可以使用哈希码方法?从我所看到的,这看起来非常复杂.我遇到了一些关于创造种子的事情.
我想知道如何解决这个问题.希望将我的哈希码的其余部分用于具有double的类?
我想知道我是否有问题试图在java中散列arraylists,数组和其他对象.我的一些课程包含arraylists.
非常感谢
可能重复:
hashCode()是如何用Java计算的
我发现Java中hashCode(?的根类方法没有实现Object:
public native int hashCode();
Run Code Online (Sandbox Code Playgroud)
如果我有一个Object a和一个Object b,我如何知道a.hashCode()和b.hashCode()价值而不使用System.out.println()?只是通过hashCode实施.
我尝试了new两个ArrayList对象,令我惊讶的是,hashCode()值是相同的:它们都是1.
我有一个用Java编写的JSON Schema实现,它依赖于Jackson(版本2.1.x).出于准确性原因,我告诉杰克逊使用BigDecimal浮点数.
对于JSON Schema的需求,特别需要:对于数值,JSON值相等由其数学值的相等性定义.我需要这种检查,因为,例如,这不是一个合法的模式(一个enum应该是唯一的值):
{ "enum": [ 1, 1.0 ] }
Run Code Online (Sandbox Code Playgroud)
但对于JsonNodes 1和1.0不相等.因此,我编写了番石榴等效的实现,并Set<Equivalence.Wrapper<JsonNode>>在适当的地方使用.此实现应适用于所有类型的节点,而不仅仅是数字节点.
而这个实现中最困难的部分原来是doHash()数字节点:/我需要相同的哈希码来获得等效的数学值,无论它们是整数还是浮点数.
我现在能想到的最好的是:
@Override
protected int doHash(final JsonNode t)
{
/*
* If this is a numeric node, we want a unique hashcode for all possible
* number nodes.
*/
if (t.isNumber()) {
final BigDecimal decimal = t.decimalValue();
try {
return decimal.toBigIntegerExact().hashCode();
} catch (ArithmeticException ignored) {
return decimal.stripTrailingZeros().hashCode();
}
} …Run Code Online (Sandbox Code Playgroud) 我正在寻找Object.hashCode()的算法.
此代码在Object.java中是本机代码.
这是因为
(a)代码在汇编中 - 从来没有在Java或任何其他HLL中
要么
(b)根本没有披露
?
在任何一种情况下,我都希望得到"如何计算hashCode()的算法(伪代码或一些详细解释)" - 它的计算中的参数和计算本身是什么?
请注意:这是 我正在寻找的Object的hashCode() -而不是像String或hashMap/table那样的.
// ================================================ ==========================
在新的Java文档 - JDK 8现在说
"The value returned by hashCode() is the object's hash code, which is the object's memory address in hexadecimal."
Run Code Online (Sandbox Code Playgroud) 我正在写一个类Vec2D,代表一个二维向量.我存储x和y在double秒.
当被要求生成equals(Object obj并且hashCode(),eclipse生成了这个:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null) …Run Code Online (Sandbox Code Playgroud) 在审查大型代码库时,我经常会遇到这样的情况:
@Override
public int hashCode()
{
return someFieldValue.hashCode();
}
Run Code Online (Sandbox Code Playgroud)
程序员不是为类生成自己唯一的哈希码,而是从字段值继承哈希码.我的直觉(也可能是消化问题)告诉我这是错的,但我不能把手指放在上面.如果有这种实施,会出现什么问题?