2014-06-22 19 views
8

試圖使用Java的DelayQueue,我必須實現Delayed接口,它需要一個compareTo()"method that provides an ordering consistent with its getDelay method."。目的當然是DelayQueue可以很容易地對排隊的對象進行排序,以便延遲的下一個可以返回給任何接受者。java.util.concurrent.Delayed是否真的迫使我違反equals/compareTo一致性?

現在我還需要提前從隊列中刪除對象。我需要致電delayQueue.remove(queuedObject)。這當然只適用於排隊的對象有一個反映它們的有效載荷的方法,而不是完全不相關的剩餘延遲時間的equals()方法。

結果,compareTo()是基於剩餘延遲時間,而equals()基於排隊的對象的有效載荷,所以他們並不一致,如「強烈推薦」的javadoc of Comparable

問題:我錯過了什麼,或者這在DelayQueue的設計中確實有點怪誕嗎?

+3

嗯,它是「強烈建議(雖然不是必需的)」,所以我不會說你必須違反某些東西。 JRE中有一些類的'compareTo'與'equals'不一致,包括'ScheduledFutureTask',它實現'Delayed'。 – izstas

+1

另請參閱http://stackoverflow.com/questions/8446736/when-using-the-delayqueue-of-java-should-i-implement-equals-and-hashcode-as – Raedwald

回答

0

可用的擺動房間可能在需求的模糊性上,其排序是一致的及其getDelay方法。 一致是什麼意思?是否可以使用getDelay值作爲主要排序,並允許將其他屬性用作次要排序,以便爲具有相同getDelay值的對象打破關係?如果是這樣,如果equals方法需要getDelay值和compareTo方法用於打破平局的所有屬性相等,但不要求其他屬性相同,則可以。這確實意味着Delayed類必須具有值語義。

0

這兩個對象沒有足夠的不同以證明將一個在另一個之上進行排序並不意味着這些對象是相同的。作爲一個簡單的例子,人們可能希望使用不區分大小寫的字符串比較對字符串進行排序,但只有當兩個字符串的大寫/小寫用法匹配時纔將其視爲等同字符串。按照這樣的標準,「FRED」和「Fred」不是不平等的,但是相對於彼此是沒有排序的。我建議equals表示語義等價性要比與compareTo「一致」更重要。