- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个 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) 不应该 equals
和 compareTo
同意? (我假设 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.Date
在 java.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.Date
和 java.util.Timestamp
从 getTime()
返回相同的值,无论您使用哪种实现都无关紧要,关键是相同的。这种方式看起来确实是最简单的。
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/
我在这个网站上发布的代码有这个问题 https://developers.google.com/drive/quickstart-cs是 Google Drive 快速入门的开发人员站点。我按照网站上
我正在尝试制作一个非常简单的 Kafka Producer,目前正在关注 producer example除了我的制作人没有分区程序类。 将所需文件导出到 jar 后,我将它们传输到我的 Linux
问题 在java中,我有一个“Util项目”,在进行单元测试时使用另一个“Mock项目”。 我的问题是“模拟项目”也使用“Util项目”来构建一些模拟对象。 当我使用 Maven 构建项目时,我无法构
据我所知,这些包已经存在很长时间了。但是,我从未见过它们的实际用法。而且这些包似乎不成熟,不再维护。如果是,为什么这些包现在存在? 最佳答案 包裹automata被 scala.xml.dtd 使用,
关闭。这个问题需要debugging details .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 1年前关闭。 Improve this question Co
在java.util.Collections中,有一个方法: public static void fill(List list, T obj) 用第二个参数指定的对象填充第一个参数指定的List。
我不明白它要我做什么。分配给 sentence正在工作: val sentences : java.util.List[CoreMap] = document.get(classOf[Sentence
在我的 React 应用程序中,我想使用一些实用程序。我见过两种不同的方法。第一个是,只是创建函数并将其导出。第二个是,创建一个 Util 类并导出一个对象,这样它就不能被实例化(静态类)。 clas
我有一个 util 类,它接受 String jwtToken 和 Key key 并使用 io.jsonwebtoken.jwts 解码 jwt。 但是,我无法对此进行测试。原因是,我无法模拟公钥并
我有使用目标命名空间的专有架构 xmlns:ax216="http://util.java/xsd" 这给我带来了从 java (java.util.xsd) 开始生成禁止的(由 Java 安全管理器
我正在阅读集合以查看 Javadocs 中的实现层次结构。 Collections声明为public class Collections extendds Object Collection声明为pu
我正在使用 Spring-boot 应用程序,我可以在其中连接 Azure 应用程序配置。但是当我尝试使用内容类型应用程序/JSON 读取值时出现错误。 我的Java类 @ConfigurationP
我正在使用 Spring-boot 应用程序,我可以在其中连接 Azure 应用程序配置。但是当我尝试使用内容类型应用程序/JSON 读取值时出现错误。 我的Java类 @ConfigurationP
我在使用格式说明符时遇到问题。这是否意味着我正在使用 %d? public static void main(String[] args) { double y, x; for (x =
鉴于此代码 import java.util.Iterator; private static List someList = new ArrayList(); public static void
我正在 HackerEarth 解决问题,我无法弄清楚为什么我的程序在命令行上正确运行并给出正确的结果,但在代码编辑器上运行时却给出 java.util.NoSuchElementException
我正在尝试使用以下代码使用对象列表列表中的数据填充tableModel readExcel.readSheet(0): TableModel tableModel = new DefaultTabl
java.util.Set 、 java.util.List 和其他 Collection 接口(interface)不可序列化。需要一个简单、直接的解决方案来在可序列化的 POJO 中使用它。 pu
我试图从 servlet 返回数据库搜索结果的 ArrayList 以显示在 jsp 页面上。 在servlet中设置arraylist作为请求的属性,并将请求转发到jsp页面。当我尝试在 jsp 页
我是android新手,最近我试图从firebase中提取数据到recyclerview/cardview中以垂直布局显示数据,它显示将Hashmap转换为Arraylist的错误,其中代码是:
我是一名优秀的程序员,十分优秀!