- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
已接受答案的调查和详细信息在问题的评论中。
我有一个小型 Java 项目,它读取时间表并将 Joda-Time Intervals 放入排序的 map (在本例中为 TreeMap)以进行进一步处理。这是通过 ScheduledExecutorService 完成的:
executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
doWork();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}, 1, 1, TimeUnit.SECONDS);
doWork()
然后读取文件,创建一些间隔,然后使用此比较器(在 map 构造函数中指定)填充 map :
@Override
public int compare(Interval o1, Interval o2) {
return o1.getStart().compareTo(o2.getStart());
}
代码随后在插入第一个间隔时在比较器中中断。通常我会认为间隔本身有问题,但是我检查了几种可能性并注意到我迷失了很多奇怪的事情:
o1
和o2
是具有相同长时间戳的有效 DateTime。 改变
try {
doWork();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
到
try {
doWork();
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
修复它。 (即 map 填充良好,包括原始的第一个间隔)。
最后一部分让我认为这是 JIT 或 JVM 的错误,而不是代码的错误。我还探讨了这是构建问题的可能性,但似乎并非如此:
经过一些远程调试后,我重现了类似的内容:带有签名“(Lorg/joda/time/ReadableInstant;)I”的方法“compareTo”不适用于此对象
在比较器代码中设置断点时,目标对象为 class org.joda.time.DateTime
。
任何有关如何进一步调试的帮助将不胜感激。
编辑:
private void doWork() {
SortedMap<Interval, String> map = new TreeMap<>(new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
return o1.getStart().compareTo(o2.getStart());
}
});
Collection<String> col1 = new HashSet<>();
Collection<String> col2 = new HashSet<>();
String string = "";
long ts = 0;
try (FileInputStream input = new FileInputStream(fileName);
InputStreamReader isr = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isr)) {
String line = reader.readLine();
map.put(new Interval(new DateTime(), new DateTime()), "");
}
}
虽然由于有很多额外代码,这看起来不像 SSCCE,但如果我删除 Collection 声明或读取的行,或在 try block 之前将任何内容放入映射中(然后按原样执行其余部分)-一切正常。让我想到竞争条件,但是这里涉及的所有变量都是本地的(除了 fileName,它保证已经设置)。
此外,在尝试一些东西时,我发现从 2.1 切换到 Joda-time 2.3 显然可以解决问题。但是,我在他们的错误修复更新日志中看不到任何看起来甚至相关的内容。
最佳答案
这里是根据我的评论总结的答案:
远程端是否有第二个 JodaTime 版本?也许是 2.0 版之前的旧版本,其中 Comparable-handling 发生了一点变化(请参阅通用接口(interface) ReadableInstant)?在 2.0 之前,有问题的方法具有签名 compareTo(Object)
,而在 2.0 和更高版本中具有新签名 compareTo(ReadableInstant)
,另请参见 release notes .两个 joda-jar 和一个连接的类加载问题的这种情况将解释以下异常消息:
带有签名“(Lorg/joda/time/ReadableInstant;)I”的方法“compareTo”不适用于此对象,目标对象是 org.joda.time.DateTime
类。
(您的问题很棘手,值得更多投票。很高兴听到您在包含较旧 JodaTime 版本的 JRuby 库中找到了原因。)
关于java - DateTime compareTo 不适用于 DateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22810331/
我是一名优秀的程序员,十分优秀!