0

为任何类型(原子类型)多列主键生成哈希码的一般无冲突 Java 最佳实践是什么?

我考虑了几个小时并得出结论,由所有主键列连接的字符串将是唯一可靠的方法。然后在该连接字符串上调用 Java 的 hashCode 方法应该会产生一个唯一的整数。(实际上它会以某种方式模仿数据库索引的作用,但这里不确定)

对于表单的多列主键

CREATE TABLE PlayerStats
(
    game_id INTEGER,
    is_home BOOLEAN,
    player_id SMALLINT,
    roster_id SMALLINT,
    ... -- (game_id, is_home) FK to score, (player_id, roster_id) FK to team member
    PRIMARY KEY (game_id, is_home, player_id, roster_id)
)

哈希码可以这样计算:

@Override
public int hashCode()
{
    //                                                                 maxchars:
    String surrogate =   String.format("%011d", this.gameId)         //11
                       + String.format("%01d" , this.isHome ? 1 : 0) //1
                       + String.format("%011d", this.playerId)       //6
                       + String.format("%011d", this.rosterId)       //6

    System.out.println("surrogate = '" + surrogate + "'");

    return surrogate.hashCode();
}

当然,这仅适用于 HashSets 和 Hashtable 当 equals 也基于此。

我的问题:这是一个好的总体策略吗?

我可以看到即时计算可能不是最快的。您可能希望在复合键值更改时重新计算哈希码(例如,从每个对键属性进行操作的 setter 中调用 rehash() 方法。

欢迎提出建议和改进。没有任何众所周知的策略吗?一种模式?

4

1 回答 1

0

哈希码用作索引来查找数据集中具有相同代码的元素。然后使用 equals 方法在具有相同哈希码的元素集中查找匹配项。因此,生成的哈希码不必是 100% 唯一的。它只需要“足够独特”以在数据元素之间创建一个体面的分布,这样就不需要对具有相同 hashCode 值的大量项目调用 equals 方法。

从这个角度来看,生成大量字符串并在这些字符串上计算哈希码似乎是一种避免由 3 个整数和 1 个布尔比较组成的等式操作的昂贵方法。它也不一定保证哈希码值的唯一性。

我的建议是从一种简单的方法开始,将密钥的哈希码作为其组成部分的哈希码之和。如果由于所有 id 都在相似的范围内而不能提供良好的分布,您可以尝试在求和之前将 id 乘以一些不同的因子。

于 2010-07-23T22:56:05.377 回答