2

我有多个具有相似 ID 的记录。该数据库是非常遗留的。没有这样独特的列。创建日期列用于保存数据库中行创建的时间戳。我必须在 java map 中保留记录才能进行一些操作。对于记录的任何更改,它都会创建新记录。我不想将所有字段都保留在 hashcode 和 equals 中。因为,我不确定哪一列会针对 id 进行更改。

首先,我尝试使用随机数生成器来生成唯一的哈希码。有用。

其次,我决定将创建的日期列放入哈希码中。它也有效。

将日期放入哈希码有什么缺点吗?

4

3 回答 3

7

hashCode 和 equals 应该使用相同的字段,并且这些字段应该是有效的不可变的(即在添加到散列集合后不会更改)

这可以包括日期或您喜欢的任何字段。

顺便说一句,我更喜欢使用long而不是Date因为我可以使它不可变并且它稍微快一点。

如果您打算使用时间戳作为 id,您还可以通过提高毫秒(或微秒,如果您可以存储这样的时间戳)来确保它是唯一的

private static final AtomicLong TIME_STAMP = new AtomicLong();
// can have up to 1000 ids per second.
public static long getUniqueMillis() {
    long now = System.currentTimeMillis();
    while (true) {
        long last = TIME_STAMP.get();
        if (now <= last)
            now = last + 1;
        if (TIME_STAMP.compareAndSet(last, now))
            return now;
    }
}

或者

private static final AtomicLong TIME_STAMP = new AtomicLong();
// can have up to 1000000 ids per second.
public static long getUniqueMicros() {
    long now = System.currentTimeMillis() * 1000;
    while (true) {
        long last = TIME_STAMP.get();
        if (now <= last)
            now = last + 1;
        if (TIME_STAMP.compareAndSet(last, now))
            return now;
    }
}
于 2013-07-29T07:59:06.603 回答
0

如果您将某些内容放入 Map 中,那么我假设您以后想用密钥获取它。键的 HashCode() 用于标识该元素属于哪个桶。然后对桶中的所有元素使用 equals() 方法来查找匹配项。通过 hashcode() 的随机数生成器,您将无法在映射中找到键,因为如果键没有更改,hashcode() 函数每次都应该返回相同的值。

于 2013-07-29T07:59:32.370 回答
0

首先,equals()如果hashCode()您将这些对象用作.HashMap

必须有某种概念来确定这些对象彼此“相等”意味着什么。您必须以反映此概念的方式实现您的equals()和方法。hashCode()

对哈希码使用随机数是一个坏主意,除非equals()总是返回false(因此,没有两个对象彼此相等)。即使这样,您当然也不能每次hashCode()调用时都返回一个新的随机数(当您将对象存储在基于哈希的集合中时,这会导致奇怪的错误)。

使用日期作为计算的一部分没有问题hashCode(),只要它是确定两个对象是否彼此相等的标准之一。

于 2013-07-29T07:59:39.340 回答