Does java.util.concurrent.Delayed really force me to violate equals/compareTo consistency?
Asked Answered
U

2

10

Trying to use Java's DelayQueue, I have to implement the Delayed interface which requires a compareTo() "method that provides an ordering consistent with its getDelay method.". The intention is of course that the DelayQueue can easily sort the queued objects such that the next one running out of its delay can be returned to any taker.

Now I have the need to also remove objects from the queue ahead of time. I need to call delayQueue.remove(queuedObject). This of course only works if the queued objects have an equals() method that reflects their payload and not the completely unrelated remaining delay time.

As a result, compareTo() is based on the remaining delay time while equals() is based on the payload of the queued objects, so they are not consistent, as is "strongly recommended" in the javadoc of Comparable.

Question: am I missing something or is this indeed a bit of a quirk in the design of DelayQueue?

Usurious answered 22/6, 2014 at 16:22 Comment(2)
Well, it's "strongly recommended (though not required)", so I would not say you have to violate something. There're some classes in JRE which have compareTo inconsistent with equals, including ScheduledFutureTask which implements Delayed.Whitehall
See also #8447236Weigand
W
0

The available wiggle room may be in the ambiguity of the requirement that ths ordering is consistent with its getDelay method. What does consistent mean? Can it mean using the getDelay values as the primary ordering, and allowing use of other attributes as a secondary ordering, to break ties for objects that have equivalent getDelayvalues? If so, you would be OK if the equals method requires equality of the getDelay values and all the attributes that the compareTo method uses for tie breaking, but does not require equality of any other attributes. This really means that the Delayed class must have value semantics.

Weigand answered 26/6, 2014 at 23:4 Comment(0)
W
0

That two objects are insufficiently different as to justify ranking one above the other does not imply that the objects are identical. As a simple example, one may wish to sort strings using a case-insensitive string comparison, but only regard two strings as equivalent when their uppercase/lowercase usage matches. By such standards, "FRED" and "Fred" would not be unequal, but would be unranked relative to each other. I would suggest that it is more important to have equals indicate semantic equivalence than to have it be "consistent" with compareTo.

Wamble answered 25/7, 2014 at 22:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.