以下是第9项的示例代码:
public final class PhoneNumber {
private final short areaCode;
private final short prefix;
private final short lineNumber;
@Override
public int hashCode() {
int result = 17;
result = 31 * result + areaCode;
result = 31 * result + prefix;
result = 31 * result + lineNumber;
return result;
}
}
Pg 48指出:“选择值31是因为它是奇素数。如果它是偶数且乘法溢出,则信息将丢失,因为2的muiltiplication相当于转移。“
我理解乘2的概念等同于位移。我也知道当我们将一个大数乘以一个大的奇素数时,我们仍会得到溢出(因此信息丢失)。我没有得到的是为什么由大奇数素数乘法引起的信息丢失优于因大偶数乘以而导致的信息丢失。
答案 0 :(得分:6)
使用偶数乘法器,乘法后的最低有效位始终为零。对于奇数乘数,最低有效位为1或0,具体取决于result
的先前值。因此,偶数乘法器正在失去关于低位的不确定性,而奇数乘法器则保留它。
答案 1 :(得分:1)
没有大的偶数素数 - 唯一的素数就是2。
除此之外 - 使用中等素数#而不是像3或5这样的小素数的一般观点是最小化两个对象以相同的散列值结束的可能性,溢出与否。
溢出的风险本身并不是问题;真正的问题是哈希码值的分布式对于被散列的对象集。由于哈希码在HashSet,HashMap等数据结构中使用,因此您希望最大限度地减少可能共享相同哈希码的对象数,以优化这些集合的查找时间。