violates the comparison contract used by the new collection sorting algorithm
of JDK/JRE7 (TimSort).
Writing:
if (d1<d2)
return 1;
else
return -1;
violates the reflexivity condition required by the new algorithm,
because it implies that A > B AND B > A are true at the same time for a
certain set of inputs A and B (in fact for all A and B such as A = B).
The condition A > B if, and only if B < A is not satisfied.
The reason is that two equal objects are not recognized as being equal
by the previous implementation of PointOrderingStrategy#compare.
Up to JDK/JRE6, the default algorithm used for sorting collection (MergeSort)
does not care about the reflexivity condition and sort the collection given
as input without throwing an error, however the new TimSort algorithm throws
an exception when it finds that the Comparator<T> provided to sort the collection
violates the reflexivity condition.
java.lang.IllegalArgumentException: Comparison method violates its general contract!
java.util.TimSort.mergeHi(TimSort.java:868)
java.util.TimSort.mergeAt(TimSort.java:485)
java.util.TimSort.mergeForceCollapse(TimSort.java:426)
java.util.TimSort.sort(TimSort.java:223)
java.util.TimSort.sort(TimSort.java:173)
java.util.Arrays.sort(Arrays.java:659)
java.util.Collections.sort(Collections.java:217)
org.jzy3d.plot3d.rendering.ordering.AbstractOrderingStrategy.sort(AbstractOrderingStrategy.java:25)
org.jzy3d.plot3d.rendering.scene.Graph.draw(Graph.java:182)
org.jzy3d.plot3d.rendering.scene.Graph.draw(Graph.java:160)
It is possible to make JDK/JRE7 use the old algorithm by specifying the
following JVM option when starting the program:
-Djava.util.Arrays.useLegacyMergeSort=true
However it looks safer and more portable to adapt the comparator so it does
not violate the contract, like in the follwing:
if (d1<d2)
return 1;
else if (d2>d1)
return -1;
else
return 0;
The behavior should be the same, without throwing exceptions when run
on JDK/JRE7.
I added a test org.jzy3d.tests.TestPointOrderingStrategy#testPointOrdering
that fails with previous sorting implementation on JDK/JRE7 without the
-Djava.util.Arrays.useLegacyMergeSort=true options. The test is successfull
with the new implementation of PointOrderStrategy#compare(Coord3d, Coord3d)
on both JDK/JRE6 and 7.