I want to apply a custom sorting comparator
as follows:
myString.sortWith{ case (c1,c2) => c1.compareTo(c2) <= 0}
This should sort the characters of the string by their codepoint values.
However it does not always work.. Consider a simple string cab312
:
val str = "cab312"
str.sortWith{ case (c1,c2) => c1.compareTo(c2) <= 0}
res0: String = 123abc
That works fine. Consider a more complex string:
scala> val str = "TOADS POOLS hoppin good service & repair"
str: String = TOADS POOLS hoppin good service & repair
scala> str.sortWith{ case (c1,c2) => c1.compareTo(c2) <= 0}
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:899)
at java.util.TimSort.mergeAt(TimSort.java:516)
at java.util.TimSort.mergeCollapse(TimSort.java:441)
at java.util.TimSort.sort(TimSort.java:245)
at java.util.Arrays.sort(Arrays.java:1438)
at scala.collection.SeqLike$class.sorted(SeqLike.scala:648)
at scala.collection.immutable.StringOps.sorted(StringOps.scala:29)
at scala.collection.SeqLike$class.sortWith(SeqLike.scala:601)
at scala.collection.immutable.StringOps.sortWith(StringOps.scala:29)
... 32 elided
So .. we get a java.lang.IllegalArgumentException: Comparison method violates its general contract!
What is going on here? How can the same comparator
both succeed and fail.. Is this a bug in the timsort
- and in any case is there a workaround?