I'd like to implement a method that compares two Objects of my interface Task
. Since there will only be a strict partial ordering on Task
, partialCompareTo
should return null
if and only if the two objects are incomparable.
If you are confused by the concept of a strict partial ordering, check this out: https://en.wikipedia.org/wiki/Partially_ordered_set
Motivation: Some tasks will have the constraint that they have to be done before or after another task. This is then used to topological sort the tasks, i.e. arrange them in a way that all constraints are met.
It should have the following property, for any instances of Task
a
and b
:
- if
a.partialCompareTo(b) != null
thensgn(a.partialCompareTo(b)) = -sgn(b.partialCompareTo(a))
- if
a.partialCompareTo(b) = null
thenb.partialCompareTo(a) = null
Note: I can't use the interface Comparable
of the standard library since there will be no total ordering on Task: compareTo
in Comparable
returns int
, so there is no way for an adequate result if two objects are incomparable. In particular there will be implementations of Task, where instances of that implementations are never comparable to each other (but might be comparable to instances of other subclasses of Task, which override partialCompareTo
).
The idea is to use the partialCompareTo
method of the argument if it overrides the method specified in the class Task
.
The following approach is actually more of a joke than an actual attempt, since every time two not comparable objects are compared we get an StackOverflowError (which is caught, but anyway this is not feasible):
public class Task implements TopologicalComparable<Task> {
/*
* other code
*/
@Override
public Integer partialCompareTo(Task other) {
Integer result;
try {
result = - other.partialCompareTo(this);
} catch (StackOverflowError | NullPointerException e) {
return null;
}
return null;
}
}
The following implementation is clearly better, but it has the downside, that one always has to override the helper method overridesDefaultPartialCompareTo
:
public class Task implements TopologicalComparable<Task> {
/*
* other code
*/
@Override
public Integer partialCompareTo(Task other) {
if (other.overridesDefaultPCompareTo()) {
Integer revComp = other.overridesDefaultPartialCompareTo(this);
if (revComp != null) {
return - revComp;
}
}
return null;
}
public default boolean overridesDefaultPartialCompareTo() {
return false;
}
}
Is there a way to ask, whether the method is overwritten in code?
Or is there an alternative approach to solve my problem?