.Net等效于Java的System.identityHashCode() [英] .Net equivalent of Java's System.identityHashCode()

查看:115
本文介绍了.Net等效于Java的System.identityHashCode()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java的 System.identityHashCode()

Java's System.identityHashCode()

为给定对象返回与将返回的哈希码相同的哈希码 通过默认方法hashCode(),无论给定对象的 类会覆盖hashCode().

Returns the same hash code for the given object as would be returned by the default method hashCode(), whether or not the given object's class overrides hashCode().

该哈希码基于对象标识,因此对于同一对象,无论对象在两次调用identityHashCode()之间是否发生突变,哈希码都将始终相同.

That hash code is based on the object identity, so it will always be the same for the same object, no matter if the object is mutated between calls to identityHashCode().

除此之外,任何两个活动对象(带有某些Java运行时)之间都不会发生哈希冲突:(前者是Oracle在下面给出的源代码中的不准确陈述,如Jai的答案显示出来了,正如另一个错误报告所指出的那样-基本上使我原来的问题无效...)

In addition to that, there will not be hash collisions between any two living objects (with some Java runtimes): (the former is an inaccurate statement by Oracle in the source given below, as Jai's answer shows, and as another bug report points out as well - which basically invalidates my original question...)

[...]垃圾对象很容易回收,地址空间为 重用. Collisons是地址空间重用的结果.如果原来 对象保持活动状态(未GCed),那么您将不会遇到此问题 问题.

[...] garbage objects are readily reclaimed and the address space is reused. The collisons result from address space reuse. If the original object remains live (not GCed) then you will not encounter this problem.

来源

.Net中有 RuntimeHelpers.GetHashCode() ,它满足第一个条件,但不满足第二个条件:

In .Net, there is RuntimeHelpers.GetHashCode(), which fulfills the first condition, but not the second:

请注意,GetHashCode始终为相同的对象引用返回相同的哈希码.但是,事实并非如此:相等的哈希码并不表示相等的对象引用.特定的哈希码值对于特定的对象引用不是唯一的.不同的对象引用可以生成相同的哈希码.

Note that GetHashCode always returns identical hash codes for equal object references. However, the reverse is not true: equal hash codes do not indicate equal object references. A particular hash code value is not unique to a particular object reference; different object references can generate identical hash codes.

.Net中是否有Java的identityHashCode()之类的东西?

So is there anything like Java's identityHashCode() in .Net?

建议与不是C#对象中的对象的内存地址相同,作为内存地址不能在这里使用(仅),因为内存管理会移动对象,因此地址在对象的生存期内可能会更改.

It was suggested that this is the same as Memory address of an object in C# which it is not, as the memory address cannot be used here (solely), as memory management moves objects around, hence the address may change during the lifetime of an object.

推荐答案

当前Java的Object#hashCode()System#identifyHashCode()不会确保返回唯一值.对此已经有疑问,并且就是一个例子.

Currently Java's Object#hashCode() and System#identifyHashCode() do not ensure unique values to be returned. There is already questions on this, and this is an example.

您提到了一个错误报告,该报告指出发生冲突的原因是 ,因为对象被垃圾回收,并且相同的内存地址被重用.但是,修改相同的测试用例将证明相反:

You have mentioned a bug report which states that collision occurred because objects were garbage collected, and the same memory address is reused. However modifying the same test case would prove otherwise:

List<Object> allObjs = new ArrayList<>(); // Used to prevent GC
Set<Integer> hashes = new HashSet<Integer>(1024);

int colls = 0;
for (int n = 0; n < 100000; n++)
{
    Integer obj = new Integer(88);
    allObjs.add(obj); // keep a strong reference to prevent GC
    int ihash = System.identityHashCode(obj);
    Integer iho = Integer.valueOf(ihash);
    if (hashes.contains(iho))
    {
        System.err.println("System.identityHashCode() collision!");
        colls++;
    }
    else
    {
        hashes.add(iho);
    }
}

System.out.println("created 100000 different objects - "
        + colls
        + " times with the same value for System.identityHashCode()");

System.out.println("Size of all objects is " + allObjs.size());
System.out.println("Size of hashset of hash values is " + hashes.size());

结果:

System.identityHashCode() collision!
System.identityHashCode() collision!
System.identityHashCode() collision!
created 100000 different objects - 3 times with the same value for System.identityHashCode()
Size of all objects is 100000
Size of hashset of hash values is 99997

在链接的SO问题中,还提到了在JRE的某些实现中,大大降低了冲突率.但是,似乎没有实现能够阻止 all 冲突.因此,即使在Java中,也无法确保哈希码的唯一性.

In the linked SO question, it was also mentioned that in some implementations of JRE, the rate of collision is greatly reduced. However, it does seem like no implementation has managed to prevent all collisions. Therefore, there is no way of ensuring uniqueness of hash codes even in Java.

因此,不要简单地基于一种来源.评论它的人也只是Oracle团队的成员,而他或她很可能不是设计这个人的人.

Therefore, don't simply believe based on one source. The person commenting it is also just a member of the Oracle team, and he or she is most likely not the person designing this.

在C#和Java中,您都必须创建自己的某种独特的数字生成器.因此,NPras提供的解决方案似乎适用于.NET.

In both C# and Java, you would have to create your own unique number generator of some kind. So the solution provided by NPras seems to do that for .NET.

这篇关于.Net等效于Java的System.identityHashCode()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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