I created the following class and an object which implements Ordering
//class person
class Person (s:String, i:Int, d:Date) {
val name = s
override def toString = name
val age = i
val dob = d
}
/*
logic for how to compare two Person objects. Their names will be compared first. If names are same, then their age will be compared. If their age is also same, then their date of birth will be compared. Note that we could have used any other logic to compare two person objects.
*/
implicit object myPersonOrdering extends Ordering[Person] {
override def compare(x: Person, y: Person) = if (x.name.compareTo(y.name) == 0) {
if (x.age.compareTo(y.age) == 0) {
x.dob.compareTo(y.dob)
} else (x.age.compareTo(x.age))
} else (x.name.compareTo(y.name))
}
//create a list of Persons
val a1 = new Person("Andy",11, new Date())
val a2 = new Person("ann",12,new Date())
val a3 = new Person("Beth",31, new Date())
val a4 = new Person("Danny",10, new Date())
val a5 = new Person("peter",1, new Date())
val la = List(a1,a2,a3,a4, a5)
la.sortBy(x=>x)
I am trying to understand where the function compare is used in sortBy. Looking at source code of SeqLike.scala, the method sortBy calls method sorted which calls method java.util.Arrays.sort(arr, ord.asInstanceOf[Ordering[Object]]). Does compareTo get called in Java code?
Yes. The java.util.Arrays.sort
method takes a Comparator, which Ordering extends. The compare
method is called inside the TimSort algorithm used by the sort
method.
The answer is "Yes". You would have understood this if you had gone bit more into the java code as well.
Here is the call in the Scala method sorted
java.util.Arrays.sort(arr, ord.asInstanceOf[Ordering[Object]])
Notice Ordering
is type casted to Comparator
. Java sort
method takes Comparator
Here is the implementation of ordering
trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializable {
outer =>
....
}
Notice Ordering
extends Comparator
.
Below is the Java sort
method which takes Comparator
. As Ordering
is also a Comparator
because Ordering
extends Comparator
. Ordering
is passed as an argument by explicit typecasting to Comparator
.
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
Short answer : YES
If you've worked with Java before, you'll know that it contains a simillar concept to Scala's Ordering - Comparator , obviously without the implicit functionality.
Also, if you look at the definition of Ordering[T] you will see that it extends said java Comparator[T] interface.
So, on calling java.util.Arrays.sort execution proceeds exactly as if this call had come from java code using a Comparator. If you look at java.util.Arrays.sort, you will see that it in turn calls TimSort.sort- which in turns calls TimsSort.binarySort where the algorithm is actually implemented (and .compare called).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.