哈希码是只是保证是为每一个类型的对象的“相同”与原始对象相同的数字。
这意味着为每个哈希码调用返回“0”将是有效的,但是自我毁灭。问题是可以(并且在大多数情况下会)是重复的。
如果您知道对象的哈希码,则无法访问它。按照我上面的例子,如果所有的对象都返回“0”,你仍然不能问哪个对象有散列码0.然而,你可以要求所有具有散列码0的对象并查看它们(这是散列表的作用,它通过获得具有相同哈希代码的代码来减少迭代次数,然后查找这些代码)。
如果您要设置(更改)HashCode,它不会是散列码,因为给定的“状态”对象的值不能更改。
至于“最好的办法”做到这一点,返回相同哈希码的唯一对象越少,您的哈希表将执行得越好。如果你有一个很长的“int”列表,你可以使用这个int值作为你的哈希码,并且你会得到这个罕见的完美哈希值 - 其中每个对象都映射到一个哈希码。
请注意,哈希表不适合存储ints的这种情况。对于那些试图存储复杂对象的情况来说更好,因为这些复杂对象不易通过其他机制进行唯一标识或比较。
你的“Int列表”的问题是,如果你有数字5并且你想在你的表格中查找它,你只需要在那里找到一个数字5。
现在,如果你想看看数字5是否存在于你的表格中,那就是另一回事了。
对于一组数值很少的孔,您可以制作一个简单的布尔数组。如果[5]存在(是),则列表中的a比a更大。如果你的一组数字非常稀疏(1,5,10002930304),那么这将不是一个很好的解决方案,因为你会在第2,3,4点存储“False”,然后在最后一堆点中存储“False”数字,但它是一个直接查找,无论您添加多少个数字,O(1)都不再需要一个步骤。
通过将这种类型的存储变成二进制查找到字节数组,您可以使这种类型的存储变得更加密集,但除非您对位操作非常好,否则可以跳过它。它会涉及这样的东西:
public boolean doesNumberExist(int number) {
return bytes[number/8] & (1 << number % 8);
}
如果您的最高号码真的很大,这仍然会用完内存。
因此,对于一个大的稀疏列表,我会使用排序的整数数组而不是轻度填充的布尔数组。一旦它被排序为一个数组,你只需进行二分搜索;从排序后的数组中间开始,如果你想要的数字更高,那么将中间的上半部分分在中间,并检查该数字,重复。
排序后的int数组需要更多的步骤,但不会有太多的步骤,它不会浪费任何内存来存储不存在的数字。
您的要求不足以确定最有效的数据结构。 首先,你如何访问该列表的元素?你会以某种未指定的顺序遍历它们吗?你会通过列表索引来查找它们吗?你会搜索列表中的值吗?然后你提到一个哈希表。散列表将关键字与值相关联。但是你的数据来自一个列表。列表元素是键还是值?或两者? – meriton 2010-06-29 23:36:45
谢谢你的问题。 Int的大列表作为我通过索引访问的查找表。那么我猜索引是关键,列表元素是值。 希望澄清它。 – Skuge 2010-06-30 07:06:59