大数据学习之路65-scala的泛型与隐式转换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37050372/article/details/82468326

scala的泛型用[]

正常写法:extends Comparable[Boy]

[T <: Comparable]    上界  upper bound

[T  >: Comparable]   下界   lower bound

[T : Comparable]    上下文界定  context bound

[T % Comparable]   视图界定   view bound

[+T]     协变  

[-T]    逆变

1.假如我们有一个用泛型指定的比较方法,他是通过comoareTo方法比较的。可是Girl没有compareTo方法怎么办?我们可以让Girl实现Comparable接口,然后重写compareTo方法即可,代码如下:

package com.test.test3

class Pair [T <: Comparable[T]]{
    def bigger(first:T,second:T): T ={
      if(first.compareTo(second)>0) first else second
    }
}
object Pair{
  def main(args: Array[String]): Unit = {
    val p = new Pair[Girl]
   val g =  p.bigger(new Girl("zhangsan",100,19),new Girl("lisi",99,16))
    println(g.name)
   
  }
}
package com.test.test3

class Girl (val name:String,val fv:Int,val age:Int) extends Comparable[Girl]{
  override def compareTo(o: Girl): Int = {
    if(this.fv == o.fv)
      this.age - o.age
    else
     o.fv - this.fv
  }
}

Pair使用的是上界

接下来我们看看视图界定。

扫描二维码关注公众号,回复: 3186059 查看本文章

同样是compareTo方法,但是假如我们传进去的值是Int类型的如果还使用上界就会报错,他报的错是泛型的错误。而不是不能隐式转换。因为Int方法没有实现comparable接口根本就不能比较。所以这个时候就需要视图界定来忽略泛型,强制隐式转换,因为preDef中有Int到Integer的隐式转换,而Integer有compareTo方法

package com.test.test3

class Pair [T <% Comparable[T]]{
    def bigger(first:T,second:T): T ={
      if(first.compareTo(second)>0) first else second
    }
}
object Pair{
  def main(args: Array[String]): Unit = {
   
    val p2 = new Pair[Int]
    val i =  p2.bigger(10,100)
    println(i)
  }
}

我们如果不使用上界和视图界定的话能不能实现上面的要求呢?

其实我们还可以使用柯里化来实现:

package com.test.test3

class Pair2[T] {
     def bigger(first:T,second:T)(implicit f: T => Comparable[T]): T ={
       if(first.compareTo(second)>0) first else second
     }
}
object Pair2{
  def main(args: Array[String]): Unit = {
    val p = new Pair2[Int]
    val i = p.bigger(1,5)
    println(i)
  }
}

假如我们希望使用compareTo方法比较两个boy可是我们并不想让boy实现Comparable接口,这个时候我们可以自定义隐式转换,并导入这个隐式转换。

Boy类:

package com.test.test4

class Boy(val name:String,val age:Int)

自定义的隐式转换:

package com.test.test4

object MyPreDef {
    implicit val f= (b:Boy) => 
    {
            new Comparable[Boy]
          {
                override def compareTo(o: Boy): Int = {
                   b.age - o.age
                }
          }
    }
}

比较类:

package com.test.test4

class Pair[T <% Comparable[T]] {
    def choose(first:T,second:T): T ={
          if(first.compareTo(second)>0) first else second
    }
}
object Pair{
  def main(args: Array[String]): Unit = {
    import com.test.test4.MyPreDef._
      val p = new Pair[Boy]

      val b = p.choose(new Boy("zhangsan",19),new Boy("lisi",20))
    println(b.name)
  }
}

上下文界定需要一个隐式值(object)

package com.test.test5

class Pair[T:Ordering] {
    def select(first:T,second:T):T = {
             val o = implicitly[Ordering[T]]
             if(o.gt(first,second)) first else second
    }
}
object Pair{
  def main(args: Array[String]): Unit = {
    import MyPreDef._
    val p = new Pair[Boy]
    val boy: Boy = p.select(new Boy("zhangsan",19),new Boy("lisi",20))
    println(boy.name,boy.age)
  }

}
package com.test.test5

class Boy(val name:String, val age:Int)
package com.test.test5

object MyPreDef {
    implicit object girl2Ordering extends Ordering[Boy]{
      override def compare(x: Boy, y: Boy): Int = {
         x.age - y.age
      }
    }
}

柯里化的方式:

猜你喜欢

转载自blog.csdn.net/qq_37050372/article/details/82468326
今日推荐