大数据系列修炼-Scala课程44

来源:互联网 发布:淘宝信用查询网 编辑:程序博客网 时间:2024/05/01 01:26

大数据系列修炼-Scala课程44


核心内容:
1、Scala中View Bounds代码实战及其在Spark中的应用源码解析


1、Scala中View Bounds的重要应用

1>在scala的类型变量限定当中,Int,Double类型本来是不是Comparable[T]的子类,但是通过视图界定<%,Int,Double类型可以隐式
的转换为Comparable[T]的子类。
注意:只有Java中的基本数据类型和用户自定义的数据类型并且实现了Comparable接口中的compareTo方法,才能使用视图界定<%的方式。
2>Ordered是Comparable接口的子类,并在其基础上面提供了一些常用的关系操作符。
3>通过Ordered中的关系操作符,我们可以方便的对两个对象进行比较,而不需要用compareTo这种方法。
4>只有在视图界定<%的前提下,我们才可以使用Ordered;若是直接的应用类型变量上界的方式,我们是不可以直接使用Ordered。
5>视图界定<%比类型变量的上界<:更加常用。


本篇博客将详细的介绍视图界定在Scala中的由来与重要性:
实例程序1:Scala中类型变量上界的应用:

object App {        def main(args:Array[String]):Unit=           {          val aa = new A[String]("Spark","Hadoop")        println(aa.bigger()) //Spark        /***************问题由来1:************/        //val bb = new A[Int](100,200) 本行将报错     }}class A[T<:Comparable[T]](val first:T,val second:T)  //注意类型变量上界的方式:T<:Comparable[T]{    def bigger() = if(first.compareTo(second)>0) first else second}

正如上面程序所示:Int类型不是Comparable[Int]的子类。解决措施:引入视图界定。

实例程序2:Scala中视图界定的应用:

object App {        def main(args:Array[String]):Unit=           {          val aa = new A[String]("Spark","Hadoop")        println(aa.bigger()) //Spark        val bb = new A[Int](100,200)        println(bb.bigger()) //200     }}class A[T<% Comparable[T]](val first:T,val second:T)  //注意类型变量上界的方式:T<:Comparable[T]{    def bigger() = if(first.compareTo(second)>0) first else second}

正如上面的程序所示:在scala的类型变量限定当中,Int类型本来是不是Comparable[Int]的子类,但是通过
视图界定<%,Int类型可以隐式的转换为Comparable[T]的子类。其实这句话我原本是打算这么总结的:在scala的类型变量限定当中,
Java中的基本数据类型Int,Double等本来是不是Comparable[T]的子类,但是通过视图界定<%,Java中的基本数据类型Int,Double
可以隐式的转化为Comparable[T]的子类.

对于实例程序2,还有一个问题:根据我们正常的数学逻辑思维,通常我们在比较两个对象的时候,习惯用< >这种数学符号,而不是
compareTo这种方式。即不是用:first.compareTo(second)>0,这个问题的解决措施:引入Ordered[T]的方式,如下所示:

实例程序3:Ordered[T]的方式:

object App {        def main(args:Array[String]):Unit=           {          val aa = new A[String]("Spark","Hadoop")        println(aa.bigger()) //Spark        val bb = new A[Int](100,200)        println(bb.bigger()) //200     }}class A[T<% Ordered[T]](val first:T,val second:T)  //注意类型变量上界的方式:T<:Comparable[T]{    def bigger() = if(first > second) first else second}

那么,ordered这个东西到底是什么呢?我们参看源码:

实例程序4:Ordered的源码:

trait Ordered[A] extends Any with java.lang.Comparable[A]   * Returns `x` where:   *   *   - `x < 0` when `this < that`   *   *   - `x == 0` when `this == that`   *   *   - `x > 0` when  `this > that`   *   */

我们可以看出,Ordered在Comparable[T]的基础上面提供了一些关系操作符。


实例程序5:深度思考1
为什么类型变量的上界定义中T <: Comparable[T]中的Int不能是Compareble[Int]的子类即下界,但是在视图界定中T <% Comparable[T]中的Int就可以是Compareble[Int]的子类呢??
答案:因为视图界定相比于类型变量的上下界的优势在于视图界定背后进行了隐式转换,可以将Int隐式的转化为Integer,甚至可以隐式的转化为RichInt,而RichInt或者Integer可以作为Comparable[Integer]或者Comparable[RichInt]的子类。


实例程序6:深度思考2
为什么在类型变量的上下界定义中可以写T<:Comparable[T],却不可以写成T<:Ordered[T]呢?为什么非要写T<%Ordered[T]呢?
其实根本原因不是说不可以写T<:Ordered[T],而是Java或者Scala中的基本数据类型等没有实现Ordered这个特质,而对于类型变量的上下界,某个类只有是Ordered[T]的子类,才可以这么写,但是可惜的是基本数据类型并没有继承Ordered。而经过上下文定义T<%Ordered[T]中,Int可以隐式的转换为RichInt,而RichInt本身已经继承了Ordered了,所以自然可以用Ordered中的内部方法了。


实例程序7:深度思考3
到底什么时候可以用类型变量的上下界以及上下文界定呢?
关键在于这两个Scala特性不是因果的关系,比如说不是随便一个类就可以进行类型或者上下文界定的,关键在于本身是否已经继承或者实现了相应的类。这也是使用这两个特性的前提。


如有问题,欢迎留言指正!

1 0
原创粉丝点击