I'm delving into the Java 8 innovations, and I'm trying to call a default method which I implement in a high-level interface, even when a subclass overrides it. I would have no problem going back to implementing a Comparator
in my BusinessLogic
class, but I was wondering if there's some magic that lets me use the nifty new ::
.
Code:
public interface IdEntity extends Comparable<IdEntity> {
int getId();
@Override
default int compareTo(IdEntity other) {
return getId() - other.getId();
}
}
public class Game implements IdEntity {
@Override
public int compareTo(IdEntity o) {
if (o instanceof Game) {
Game other = (Game) o;
int something;
// logic
return something;
}
return super.compareTo(o);
}
}
public class BusinessLogic {
private void sortList(List<? extends IdEntity> list) {
// for Game, Game::compareTo gets called but I want, in this call only, the default method
Collections.sort(list, IdEntity::compareTo);
}
}
One way would be to put the compare method in a static method:
public static interface IdEntity extends Comparable<IdEntity> {
int getId();
@Override default int compareTo(IdEntity other) {
return defaultCompare(this, other);
}
static int defaultCompare(IdEntity first, IdEntity second) {
return first.getId() - second.getId();
}
}
Then your method would be:
Collections.sort(list, IdEntity::defaultCompare);
Simpler approach: static import Comparator.comparingInt
and use
Collections.sort(list, comparingInt(IdEntity::getId));
I don't believe you can re-extract the default compareTo
implementation: it's been overridden; you usually can't run an overridden method implementation. But this will just work straightforwardly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With