【问题标题】:Does java.util.concurrent.Delayed really force me to violate equals/compareTo consistency?java.util.concurrent.Delayed 真的强迫我违反 equals/compareTo 一致性吗?
【发布时间】:2014-08-12 17:49:49
【问题描述】:

尝试使用 Java 的 DelayQueue,我必须实现需要 compareTo() "method that provides an ordering consistent with its getDelay method."Delayed 接口。目的当然是DelayQueue 可以轻松地对排队的对象进行排序,以便下一个用完延迟的对象可以返回给任何接受者。

现在我还需要提前从队列中删除对象。我需要打电话给delayQueue.remove(queuedObject)。这当然只有在队列对象有一个 equals() 方法来反映它们的有效负载而不是完全不相关的剩余延迟时间时才有效。

因此,compareTo() 是基于剩余延迟时间,而equals() 是基于排队对象的负载,因此它们并不一致,正如javadoc of Comparable 中的“强烈推荐”。

问题:是我遗漏了什么还是DelayQueue 的设计确实有点怪癖?

【问题讨论】:

  • 嗯,它是“强烈推荐(尽管不是必需的)”,所以我不会说你必须违反某些东西。 JRE 中有一些类的compareToequals 不一致,包括实现DelayedScheduledFutureTask

标签: java concurrency equals compareto


【解决方案1】:

可用的回旋余地可能存在于要求其排序与其getDelay 方法一致 的模糊性。 一致是什么意思?这是否意味着使用getDelay 值作为主要排序,并允许使用其他属性作为次要排序,以打破具有等效getDelay 值的对象的关系?如果是这样,那么如果equals 方法要求getDelay 值和compareTo 方法用于打破平局的所有属性相等,但不需要任何其他属性相等,则可以。这确实意味着Delayed 类必须具有值语义。

【讨论】:

    【解决方案2】:

    两个对象的差异不足以证明将一个对象排在另一个之上并不意味着对象是相同的。作为一个简单的例子,人们可能希望使用不区分大小写的字符串比较对字符串进行排序,但仅当两个字符串的大写/小写用法匹配时才将其视为等价的。按照这样的标准,“FRED”和“Fred”不会是不平等的,而是相对于彼此没有排名。我建议让equals 表示语义等价比让它与compareTo“一致”更重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-26
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多