I know this has been an issue for a while now, and checked all previously answers I could get, but still this one doesn't work.
The object 'crew' represents crewmembers with ranks and other items. The comparison should be made by comparing 'assigned_rank', an int value, and if this value is equal in both instances, then 'is_trainer', a boolean, should make the difference.
This method worked great as long as it was running with java < 7. But since Java 7 I keep getting this one:
java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:714) at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:451) at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:376) at java.util.ComparableTimSort.sort(ComparableTimSort.java:182) at java.util.ComparableTimSort.sort(ComparableTimSort.java:146) at java.util.Arrays.sort(Arrays.java:472) at java.util.Collections.sort(Collections.java:155) at dormas_flightlog.Query.getCrew(Query.java:714)
Here is the source, where some potentially dangerous parts have allready been out-commented, but it still does not work:
public class crew implements Serializable, Comparable<crew> { private static final long serialVersionUID = 36L; private int flightID = 0; private int assigned_rank = 25; private boolean is_trainer = false; ... @Override public int compareTo(crew him) { int myRank = this.getAssigned_rank(); int hisRank = him.assigned_rank; if (this == him) { return 0; } if (myRank > hisRank) { return 1; } if (myRank < hisRank) { return -1; } if (myRank == hisRank) { // if (is_trainer && !o.is_trainer) { // i = 1; // } // if (!is_trainer && o.is_trainer) { // i = -1; // } // if (is_trainer && o.is_trainer) { // i = 0; // } // if (!is_trainer && !o.is_trainer) { // i = 0; // } return 0; } return 0; } @Override public int hashCode() { int hash = 7; hash = 31 * hash + this.assigned_rank; hash = 31 * hash + (this.is_trainer ? 1 : 0); return hash; } @Override public boolean equals(Object o) { if (this == o) { return true; } int myRank = this.getAssigned_rank(); int hisRank = 0; if (o instanceof crew) { crew him = (crew) o; hisRank = him.assigned_rank; } else { return false; } if (myRank > hisRank) { return false; } if (myRank < hisRank) { return false; } if (myRank == hisRank) { // if (is_trainer && !o.is_trainer) { // i = 1; // } // if (!is_trainer && o.is_trainer) { // i = -1; // } // if (is_trainer && o.is_trainer) { // i = 0; // } // if (!is_trainer && !o.is_trainer) { // i = 0; // } return true; } return false; }
}
Implementing equals() was just a try to solve this problem. The given exception comes with or without equals(). I cannot see how the compareTo-method violates its contract. Any help is greatly appreciated....one day this code has to work with java 7 and I don't know how... Thanks
see this:
From http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source
Area: API: Utilities Synopsis: Updated sort behavior for Arrays and Collections may throw an IllegalArgumentException
Description: The sorting algorithm used by java.util.Arrays.sort and (indirectly) by java.util.Collections.sort has been replaced. The new sort implementation may throw an IllegalArgumentException if it detects a Comparable that violates the Comparable contract. The previous implementation silently ignored such a situation. If the previous behavior is desired, you can use the new system property java.util.Arrays.useLegacyMergeSort, to restore previous mergesort behavior.
Nature of Incompatibility: behavioral
RFE: 6804124
For more detailed info, see the bug database reference here.
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