将日期放在哈希码中是一种好习惯吗?

时间:2013-07-29 07:45:28

标签: java date map hashcode

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

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

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

将日期放在哈希码中是否有任何不利之处?

3 个答案:

答案 0 :(得分:7)

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

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

BTW我更喜欢使用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;
    }
}

答案 1 :(得分:0)

如果你在Map中放了一些东西,我假设你想稍后用密钥取出它。密钥的HashCode()用于标识元素属于哪个存储桶。然后在桶中的所有元素上使用equals()方法来查找匹配。通过为hashcode()设置一个随机数生成器,您将无法在映射中找到该键,因为如果键没有更改,hashcode()函数应该每次都返回相同的值。

答案 2 :(得分:0)

首先,如果您在equals()中将这些对象用作,则只需要hashCode()HashMap方法。

必须有一些概念决定了这些物体彼此“相等”的含义。您必须以反映此概念的方式实施equals()hashCode()方法。

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

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