简体   繁体   English

Scala中的订购工作方式

[英]How Ordering works in Scala

I created the following class and an object which implements Ordering 我创建了以下类和一个实现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. 我试图了解在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]]). 查看SeqLike.scala的源代码,方法sortBy调用sorted方法,该方法调用了java.util.Arrays.sort(arr,ord.asInstanceOf [Ordering [Object]])方法。 Does compareTo get called in Java code? 是否可以在Java代码中调用compareTo?

Yes. 是。 The java.util.Arrays.sort method takes a Comparator, which Ordering extends. java.util.Arrays.sort方法采用Comparator,Ordering对其进行了扩展。 The compare method is called inside the TimSort algorithm used by the sort method. compare方法被称为由所使用的TimSort算法中sort方法。

The answer is "Yes". 答案是“是”。 You would have understood this if you had gone bit more into the java code as well. 如果您还对Java代码进行了更多了解,您将理解这一点。

Here is the call in the Scala method sorted 这是在Scala方法中sorted的调用

java.util.Arrays.sort(arr, ord.asInstanceOf[Ordering[Object]])

Notice Ordering is type casted to Comparator . 注意Ordering类型转换为Comparator Java sort method takes Comparator Java sort方法需要Comparator

Here is the implementation of ordering 这是订购的实施

trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializable {
  outer =>
 ....
}

Notice Ordering extends Comparator . 注意Ordering扩展了Comparator

Below is the Java sort method which takes Comparator . 下面是采用Comparator的Java sort方法。 As Ordering is also a Comparator because Ordering extends Comparator . 由于Ordering也是Comparator因为Ordering扩展了Comparator Ordering is passed as an argument by explicit typecasting to Comparator . 通过显式类型转换将Ordering作为参数传递给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. 如果您以前使用过Java,那么您会知道它包含与Scala的Ordering- Comparator类似的概念,显然没有隐式功能。

Also, if you look at the definition of Ordering[T] you will see that it extends said java Comparator[T] interface. 另外,如果您查看Ordering [T]的定义,您会发现它扩展了java Comparator [T]接口。

So, on calling java.util.Arrays.sort execution proceeds exactly as if this call had come from java code using a Comparator. 因此,在调用java.util.Arrays.sort时,执行的执行过程就好像此调用来自使用Comparator的Java代码一样。 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). 如果查看java.util.Arrays.sort,您将看到它依次调用TimSort.sort-,后者依次调用TimsSort.binarySort,在该处实际实现算法(并调用.compare)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM