gpt4 book ai didi

java.util.Date equals() 似乎没有按预期工作

转载 作者:搜寻专家 更新时间:2023-10-30 19:42:46 24 4
gpt4 key购买 nike

问题

我有一个 Map<Date, Foo> , 以及来自数据库的对象列表 effectiveDate属性,我想检查一下 Date我 map 中的键等于 effectiveDate 中的任何一个s 在数据库中 - 如果是这样,用 Foo 做一些事情.

代码看起来像这样:

for (Bar bar : databaseBars) {
Foo foo = new Foo();
if (dateMap.containsKey(bar.getEffectiveDate()) {
foo = dateMap.get(bar.getEffectiveDate());
}
// do stuff with foo and bar
}

然而,dateMap.containsKey调用总是返回 false,即使我确定它有时存在。

调查

作为完整性检查,我打印了日期的长值,以及 equals() 的结果。调用compareTo()调用:

for (Date keyDate : dateMap.keySet()) {
if (keyDate == null) {
continue; // make things simpler for now
}

Date effDate = bar.getEffectiveDate();

String template = "keyDate: %d; effDate: %d; equals: %b; compareTo: %d\n";

System.out.printf(template, keyDate.getTime(), effDate.getTime(), effDate.equals(keyDate), effDate.compareTo(keyDate));
}

结果:

keyDate: 1388534400000; effDate: 1388534400000; equals: false; compareTo: 0
keyDate: 1420070400000; effDate: 1388534400000; equals: false; compareTo: -1
keyDate: 1388534400000; effDate: 1420070400000; equals: false; compareTo: 1
keyDate: 1420070400000; effDate: 1420070400000; equals: false; compareTo: 0
keyDate: 1388534400000; effDate: 1388534400000; equals: false; compareTo: 0
keyDate: 1420070400000; effDate: 1388534400000; equals: false; compareTo: -1
keyDate: 1388534400000; effDate: 1420070400000; equals: false; compareTo: 1
keyDate: 1420070400000; effDate: 1420070400000; equals: false; compareTo: 0
keyDate: 1388534400000; effDate: 1388534400000; equals: false; compareTo: 0
keyDate: 1420070400000; effDate: 1388534400000; equals: false; compareTo: -1
keyDate: 1388534400000; effDate: 1420070400000; equals: false; compareTo: 1
keyDate: 1420070400000; effDate: 1420070400000; equals: false; compareTo: 0

问题

1) 不应该 equalscompareTo同意? (我假设 java.util.Date 的实现至少应该尝试遵循 java.lang.Comparable 的建议)。

2) The Date#equals doc says this :

Thus, two Date objects are equal if and only if the getTime method returns the same long value for both.

...看起来像 getTime方法为这两个日期返回相同的 long 值,但 equal返回假。任何想法为什么会发生这种情况?我到处搜索,但没有找到任何人描述相同的问题。

附言我一直在使用 java.util.Date .请不要只推荐 JodaTime。

附言我意识到我可以改变这段代码的结构并可能让它工作。但这应该可行,我不想只是解决它,除非它是一个已知问题或其他问题。这似乎是错误的

最佳答案

作为Mureinik暗示和Sotirios Delimanolis更具体地指出,这里的问题在于 java.util.Date 的实现.

java.util.Datejava.sql 中扩展了 3 个类包,所有这些似乎都做类似的事情,并且它们在 java 中的区别一点也不清楚(似乎它们存在的原因只是为了使 java 类更准确地与 SQL 数据类型对齐) - 有关它们差异的更多信息,查看this very detailed answer .

现在,在一个看似严重的设计缺陷中,有人决定制作 equals() asymmetric with java.sql.Timestamp - 即 timestamp.equals(date)即使 date.equals(timestamp) 也可能返回 false返回真。好主意。

我写了几行看哪个java.sql类展示了这个荒谬的属性 - 显然它只是 Timestamp .这段代码:

java.util.Date utilDate = new java.util.Date();

java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

System.out.println("sqlDate equals utilDate:\t" + sqlDate.equals(utilDate));
System.out.println("utilDate equals sqlDate:\t" + utilDate.equals(sqlDate));

java.sql.Time time = new java.sql.Time(utilDate.getTime());

System.out.println("time equals utilDate:\t\t" + time.equals(utilDate));
System.out.println("utilDate equals time:\t\t" + utilDate.equals(time));

java.sql.Timestamp timestamp = new java.sql.Timestamp(utilDate.getTime());

System.out.println("timestamp equals utilDate:\t" + timestamp.equals(utilDate));
System.out.println("utilDate equals timestamp:\t" + utilDate.equals(timestamp));

产生这个:

sqlDate equals utilDate:    true
utilDate equals sqlDate: true
time equals utilDate: true
utilDate equals time: true
timestamp equals utilDate: false
utilDate equals timestamp: true

java.util.HashMap uses parameter.equals(key) in it's implementation of containsKey() (而不是 key.equals(parameter) ),这个奇怪的结果出现在给定的情况下。

那么,如何解决这个问题呢?

1) 使用 Long在 map 中输入而不是 Date (正如 Mureinik 指出的那样)- 自 java.util.Datejava.util.TimestampgetTime() 返回相同的值,无论您使用哪种实现都无关紧要,关键是相同的。这种方式看起来确实是最简单的。

2) 在 map 中使用日期对象之前对其进行标准化。这种方式需要更多的工作,但对我来说似乎更可取,因为它更清楚 map 是什么 - 一堆 Foo每个都存储在某个时刻。这是我最终使用的方式,方法如下:

public Date getStandardizedDate(Date date) {
return new Date(date.getTime());
}

它需要一个额外的方法调用(而且有点荒谬),但对我来说,涉及 Map<Date, Foo> 的代码的可读性提高了是值得的。

关于java.util.Date equals() 似乎没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27661640/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com