当Java中的类不重写hashCode()时, 打印这个类的实例会得到一个很好的唯一编号。
Object的Javadoc说hashCode():
在合理实用的情况下,类Object定义的hashCode方法确实为不同的对象返回不同的整数。
但是当类重写hashCode()时,我如何获得 它唯一的数字?
当Java中的类不重写hashCode()时, 打印这个类的实例会得到一个很好的唯一编号。
Object的Javadoc说hashCode():
在合理实用的情况下,类Object定义的hashCode方法确实为不同的对象返回不同的整数。
但是当类重写hashCode()时,我如何获得 它唯一的数字?
当前回答
hashCode()和identityHashCode()返回值是不同的。对于两个不相等(用==测试)的对象o1, o2 hashCode()可能是相同的。请看下面的例子。
class SeeDifferences
{
public static void main(String[] args)
{
String s1 = "stackoverflow";
String s2 = new String("stackoverflow");
String s3 = "stackoverflow";
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
System.out.println(System.identityHashCode(s1));
System.out.println(System.identityHashCode(s2));
System.out.println(System.identityHashCode(s3));
if (s1 == s2)
{
System.out.println("s1 and s2 equal");
}
else
{
System.out.println("s1 and s2 not equal");
}
if (s1 == s3)
{
System.out.println("s1 and s3 equal");
}
else
{
System.out.println("s1 and s3 not equal");
}
}
}
其他回答
System.identityHashCode(yourObject)将给出yourObject的“原始”哈希码作为整数。独特性不一定得到保证。Sun JVM实现将为您提供一个与该对象的原始内存地址相关的值,但这是一个实现细节,您不应该依赖它。
编辑:回答修改以下汤姆的评论re.内存地址和移动对象。
javadoc for Object指定了这一点
这通常是通过将对象的内部地址转换为整数来实现的,但是JavaTM编程语言并不需要这种实现技术。
如果一个类重写了hashCode,这意味着它想要生成一个特定的id,它将(人们可以希望)具有正确的行为。
你可以使用系统。identityHashCode来获取任何类的id。
只是从另一个角度扩大其他答案。
如果你想重用来自“上面”的hashcode,并使用类的“不可变状态”派生新的hashcode,那么调用super就可以了。虽然这可能会/可能不会一直级联到Object(即某些祖先可能不会调用super),但它将允许您通过重用派生哈希码。
@Override
public int hashCode() {
int ancestorHash = super.hashCode();
// now derive new hash from ancestorHash plus immutable instance vars (id fields)
}
我想出了这个解决方案,在我的情况下,我有对象创建在多线程和序列化:
public abstract class ObjBase implements Serializable
private static final long serialVersionUID = 1L;
private static final AtomicLong atomicRefId = new AtomicLong();
// transient field is not serialized
private transient long refId;
// default constructor will be called on base class even during deserialization
public ObjBase() {
refId = atomicRefId.incrementAndGet()
}
public long getRefId() {
return refId;
}
}
hashCode()和identityHashCode()返回值是不同的。对于两个不相等(用==测试)的对象o1, o2 hashCode()可能是相同的。请看下面的例子。
class SeeDifferences
{
public static void main(String[] args)
{
String s1 = "stackoverflow";
String s2 = new String("stackoverflow");
String s3 = "stackoverflow";
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
System.out.println(System.identityHashCode(s1));
System.out.println(System.identityHashCode(s2));
System.out.println(System.identityHashCode(s3));
if (s1 == s2)
{
System.out.println("s1 and s2 equal");
}
else
{
System.out.println("s1 and s2 not equal");
}
if (s1 == s3)
{
System.out.println("s1 and s3 equal");
}
else
{
System.out.println("s1 and s3 not equal");
}
}
}