我有多个具有类似身份的记录。数据库非常遗产。没有这样独特的专栏。创建日期列用于保留数据库中行的创建时间戳。我必须在java map中保留记录以进行一些操作。对于记录中的任何更改,它会创建新记录。我不想将所有字段保留在hashcode和equals中。因为,我不确定哪个列是针对id更改的。
首先,我尝试使用随机数生成器来获取唯一的哈希码。它有效。
其次,我决定将创建的日期列放在哈希码中。它也有效。
将日期放在哈希码中是否有任何不利之处?
答案 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()
计算的一部分没有问题,只要它是确定两个对象是否彼此相等的标准之一。