I have a Vehicle class that needs to be sorted whenever I have a list of Vehicle objects. I've implemented the Comparable interface and overrode the compareTo() method.
It works, but occasionally the application crashes (this is an Android application). The error I get is java.lang.IllegalArgumentException: Comparison method violates its general contract!
.
Here's the code of the compareTo() method:
//this is used as a comparison criteria when using the Collections.sort() method on a Vehicle list
@Override
public int compareTo(@NonNull Object o) {
Vehicle v = (Vehicle) o;
try {
if (this.getVehicleParameters().getMainSwitch().equals("on") && v.getVehicleParameters().getMainSwitch().equals("on")) {
if (this.getVehicleId().compareTo(v.getVehicleId()) > 0) value = 1;
else if (this.getVehicleId().compareTo(v.getVehicleId()) == 0) value = 0;
else value = -1;
} else if (this.getVehicleParameters().getMainSwitch().equals("on") && v.getVehicleParameters().getMainSwitch().equals("off")) {
value = -1;
} else if (this.getVehicleParameters().getMainSwitch().equals("off") && v.getVehicleParameters().getMainSwitch().equals("on")) {
value = 1;
} else if (this.getVehicleParameters().getMainSwitch().equals("off") && v.getVehicleParameters().getMainSwitch().equals("off")) {
if (this.getVehicleId().compareTo(v.getVehicleId()) > 0) value = 1;
else if (this.getVehicleId().compareTo(v.getVehicleId()) == 0) value = 0;
else value = -1;
}
} catch (Exception e) {
if (this.getVehicleParameters().getMainSwitch() == null) value = -1;
else value = 1;
}
return value;
}
What it's doing is this: it first sorts by the main switch of the vehicle (if the engine is on or off) and then it sorts it alphabetically. So you get a list with the vehicles that have the engine turned on, sorted alphabetically, and then at the end of this list are the vehicles with the engine turned off, sorted alphabetically.
In the catch
block I put a simple rule that if the current object's main switch is null, then return the value -1. Else, return 1.
However, every now and then the application crashes, giving me the error java.lang.IllegalArgumentException: Comparison method violates its general contract!
Can you see what's wrong here?
PS. This is NOT a duplicate of another question simply because we're dealing with possible NULL values here, and that's when the issue arises - when it gets in the catch block. At least, that's the only reasonable explanation. The error appears randomly, maybe after 2 minutes, maybe after 30 minutes (the application is real-time).