C# net使用什么哈希算法?java呢?

C# net使用什么哈希算法?java呢?,c#,java,hashtable,C#,Java,Hashtable,关于哈希表(及其后续衍生产品),有人知道.net和Java使用什么样的哈希算法吗 列表和字典都是哈希表的直接描述吗?哈希函数没有内置到哈希表中;哈希表调用键对象上的方法来计算哈希。因此,哈希函数根据密钥对象的类型而变化 在Java中,列表不是哈希表(也就是说,它不扩展映射接口)。可以在内部使用哈希表实现列表(稀疏列表,其中列表索引是哈希表的键),但是这样的实现不是标准Java库的一部分。任何在.NET中声称是哈希表或类似的东西都不会实现自己的哈希算法:它们总是调用被哈希的对象的GetHashCo

关于哈希表(及其后续衍生产品),有人知道.net和Java使用什么样的哈希算法吗


列表和字典都是哈希表的直接描述吗?

哈希函数没有内置到哈希表中;哈希表调用键对象上的方法来计算哈希。因此,哈希函数根据密钥对象的类型而变化


在Java中,
列表
不是哈希表(也就是说,它不扩展
映射
接口)。可以在内部使用哈希表实现
列表
(稀疏列表,其中列表索引是哈希表的键),但是这样的实现不是标准Java库的一部分。

任何在.NET中声称是哈希表或类似的东西都不会实现自己的哈希算法:它们总是调用被哈希的对象的
GetHashCode()
方法


但是,对于这个方法的作用或应该做什么,存在很多困惑,特别是当涉及覆盖.NET的用户定义类或其他自定义类时。对于.NET,您可以使用Reflector查看各种算法。泛型哈希表和非泛型哈希表有不同的算法,当然,每个类都定义自己的哈希代码公式。

哈希算法是用于确定哈希表中项目的哈希代码的算法

HASHTABLE算法(我想这就是这个人要问的)是HASHTABLE根据元素的hash代码来组织元素的算法


Java碰巧使用了哈希表算法。

我对.NET一无所知,但我将尝试为Java说话

在Java中,哈希代码最终是给定对象的hashCode()函数返回的代码和HashMap/ConcurrentHashMap类中的第二个哈希函数的组合(有趣的是,这两个函数使用不同的函数)。请注意,Hashtable和Dictionary(HashMap和AbstractMap的前身)是过时的类。而列表实际上只是“其他东西”

例如,String类通过将当前代码重复乘以31并添加下一个字符来构造哈希代码。有关更多信息,请参阅我的文章。数字通常使用“自身”作为散列码;具有字段组合的其他类,例如矩形,通常使用字符串技术的组合,即乘以一个小素数并进行加法,但要在不同的字段值中进行加法。(选择素数意味着您不太可能在某些值和哈希代码宽度之间获得“意外交互”,因为它们不会被任何东西除。)

由于哈希表的大小(即它所拥有的“bucket”的数量)是2的幂,因此bucket数基本上是从哈希代码中派生出来的,方法是删掉顶部的位,直到哈希代码在范围内。第二个散列函数通过“分散位”防止散列函数中的所有或大部分随机性都在那些顶层位,从而使一些随机性最终在底层位中,而不会被截断。如果不进行这种混合,字符串哈希代码实际上可以很好地工作,但是用户创建的哈希代码可能不会工作得很好。请注意,如果两个不同的哈希代码解析为同一个bucket编号,Java的HashMap实现将使用“链接”技术——即,它们在每个bucket中创建一个条目的链接列表。因此,哈希代码具有良好的随机性非常重要,这样项就不会聚集到特定范围的存储桶中。(然而,即使有一个完美的散列函数,根据平均法则,您仍然会期望出现一些链接。)

哈希代码的实现不应该是个谜。您可以查看所选任何类的hashCode()源。

.NET
字典
类使用
IEqualityComparer
计算键的哈希代码,并在键之间执行比较,以便进行哈希查找。 如果在构造
字典
实例时未提供
IEqualityComparer
(这是构造函数的可选参数),它将为您创建默认值,默认情况下使用
对象.GetHashCode
对象.Equals
方法


至于标准的
GetHashCode
实现是如何工作的,我不确定它是否有文档记录。对于特定类型,您可以在Reflector中阅读该方法的源代码,或者尝试检查Rotor源代码,看看它是否在那里。

当我自己寻找相同的答案时,我在.net的参考源@中发现了这一点


虽然Java的哈希表确实包含一个二级哈希函数,当然是为了防止随机性不在低位的哈希函数。您应该补充的是,哈希冲突是通过一个具有相同哈希代码的条目链表来处理的。IIRC,HashMap现在的大小是2的幂,但过去不是这样。哈希表通常是从一个素数大小开始的。基本大小是有用的(只有当你的散列码是坏的(并且你没有重新散列)。Tom——是的,它是有用的,事实上,正如我所记得的,它被带到了HashMap的1.4版本之前。但是,正如你所说的,很多人认为如果你发现你需要一个基本的桶数,本质上是上帝告诉你的散列函数不够好的话。米迦勒-我会补充一些东西。注意,导致链接的都是相同的桶索引。如果两个对象的hashCode()返回相同的值,则其中一个将覆盖另一个。对于HashMap和Hashtable。IdentityHashMap(和ThreadLocal)使用探测算法。(虽然我不认为这其中有任何规定。)这详细解释了内部结构,没有猜测。确切链接如下:
     /*
      Implementation Notes:
      The generic Dictionary was copied from Hashtable's source - any bug 
      fixes here probably need to be made to the generic Dictionary as well.
      This Hashtable uses double hashing.  There are hashsize buckets in the 
      table, and each bucket can contain 0 or 1 element.  We a bit to mark
      whether there's been a collision when we inserted multiple elements
      (ie, an inserted item was hashed at least a second time and we probed 
      this bucket, but it was already in use).  Using the collision bit, we
      can terminate lookups & removes for elements that aren't in the hash
      table more quickly.  We steal the most significant bit from the hash code
      to store the collision bit.

      Our hash function is of the following form:

      h(key, n) = h1(key) + n*h2(key)

      where n is the number of times we've hit a collided bucket and rehashed
      (on this particular lookup).  Here are our hash functions:

      h1(key) = GetHash(key);  // default implementation calls key.GetHashCode();
      h2(key) = 1 + (((h1(key) >> 5) + 1) % (hashsize - 1));

      The h1 can return any number.  h2 must return a number between 1 and
      hashsize - 1 that is relatively prime to hashsize (not a problem if 
      hashsize is prime).  (Knuth's Art of Computer Programming, Vol. 3, p. 528-9)
      If this is true, then we are guaranteed to visit every bucket in exactly
      hashsize probes, since the least common multiple of hashsize and h2(key)
      will be hashsize * h2(key).  (This is the first number where adding h2 to
      h1 mod hashsize will be 0 and we will search the same bucket twice).

      We previously used a different h2(key, n) that was not constant.  That is a 
      horrifically bad idea, unless you can prove that series will never produce
      any identical numbers that overlap when you mod them by hashsize, for all
      subranges from i to i+hashsize, for all i.  It's not worth investigating,
      since there was no clear benefit from using that hash function, and it was
      broken.

      For efficiency reasons, we've implemented this by storing h1 and h2 in a 
      temporary, and setting a variable called seed equal to h1.  We do a probe,
      and if we collided, we simply add h2 to seed each time through the loop.

      A good test for h2() is to subclass Hashtable, provide your own implementation
      of GetHash() that returns a constant, then add many items to the hash table.
      Make sure Count equals the number of items you inserted.

      Note that when we remove an item from the hash table, we set the key
      equal to buckets, if there was a collision in this bucket.  Otherwise
      we'd either wipe out the collision bit, or we'd still have an item in
      the hash table.

       -- 
    */