scala之泛型

 

 

视图界定 <%

<% 有隐式转换

package com.doit.scala.yinshizhuanhuan
/* [T <: Comparable[T]] 上界  upper bound     java: <T extends Comparable>
* [T >: Comparable[T]] 下界  lower bound     java: <T super Comparable>
* [T <% Comparable] 视图界定   view bound     跟隐式转换有关的
* [T : Comparable] 上下文界定 context bound    跟隐式转换有关的
* [-T] 逆变   方法输入参数
* [+T] 协变   方法返回
* */
class Pair1[T <% Comparable[T]] {
  def bigger(first: T,second:T):T={
    if(first.compareTo(second)>=0)first else second
  }
}
object Pair1{
  def main(args: Array[String]): Unit = {
    //首先,先用Int类型举个例子
    //Int并没有实现Comparable接口没有compare方法的,
    // 如果是<: 就不能实现下面方法
    //<% 就能够实现以下方法 因为<% 有隐式转换
    // 在Ordering中有隐式转换
    val p1 = new Pair1[String]
    val i = p1.bigger("hl", "xg")
    println(i)
  }
}

上界 upper bound

 

在设定上界中,不需要implicit方法,只需要在需要比较的类中继承Ordered,添加上泛型,然后重写compare方法

package com.doit.scala.yinshizhuanhuan

import com.doit.scala.day05.Girl

class Pair2 [T <: Ordered[T]]{
  //Scala中用于比较的两个类:Ordered、Ordering
  //Ordered 实现了java.lang.Comparable接口,对Comparable进行了扩展,更灵活,用气量更方便
  //Ordering 实现了java的 Comparator接口,同时对Comparator进行了扩展
  def select(first: T,second: T): T={
    if(first >= second) first else second
  }
}
object Pair2{
  def main(args: Array[String]): Unit = {
    
    val girl = new Pair2[Girl]
    val zh = new Girl("zh", 99)
    val qj = new Girl("qj", 59)
    println(girl.select(zh,qj).name)
  }
}





package com.doit.scala.day05

class Girl(val name: String,val fv: Double) extends Ordered[Girl]{
  override def compare(that: Girl): Int =
    (this.fv-that.fv).toInt//降序

}

 

视图界定 view bound

如果传入的泛型 是视图界定的 但是并没有在类中或者方法中定义比较方法,就需要在 new出比较方法实例的之前将 implicit导进来,传进来的 implicit可以是函数,也可以是方法,优先导入函数,如果没有函数就将方法转换成函数导入

package com.doit.scala.yinshizhuanhuan

import com.doit.scala.day05.Boy

class Pair3[T <% Ordered[T]] {
  def choose (first: T,second: T):T ={
    if(first > second)first else second
  }
}
object Prir3{
  def main(args: Array[String]): Unit = {
    import ContextDemo._
    val p3 = new Pair3[Boy]
    val hulei = new Boy("hulei", 2)
    val caojianxi = new Boy("caojianxi", 100000)
    val boy = p3.choose(hulei, caojianxi)
    println(boy.name)
  }
}



package com.doit.scala.yinshizhuanhuan

class Boy (val name: String,val fv: Int){

}




implicit def Boy2(boy: Boy):Ordered[Boy]=new Ordered[Boy] {
    override def compare(that: Boy): Int = {
      (boy.fv-that.fv).toInt
    }

上下文界定 context bound

相当于直接将泛型准确的锁定在对应类上

需要传入一个隐式类型 类  而不是方法或者函数

package com.doit.scala.yinshizhuanhuan
//context bound 上下文界定,就是实现隐式转换
//上下文界定 需要传入一个隐式类型 类
class Pair4 [T : Ordering]{
  def bigger (first :T,second: T):T={
    val ord: Ordering[T] = implicitly[Ordering[T]]   //本来是毫无关系的T 和 Ordering的两个类 需要用implicitly方法 使两个类关联起来
    if(ord.gteq(first,second))first else second
  }
}
object Pair4{
  def main(args: Array[String]): Unit = {
    import ContextDemo._
//    val p4 = new Pair4[Man]
//    val hulei = new Man("hulei", 78)
//    val caojianxi = new Man("caojianxi", 18)
//    println(p4.bigger(hulei,caojianxi).name)   //hulei


    //    //明明需要Ordering[Man]类型的参数,但是你给的是Ordered[Man]的函数或方法
//    //说明幕后有一个神奇的力量,可以将Ordering[T]转成Ordered[T]
    val p4 = new Pair4[Man]
    val hulei = new Man("hulei", 78)
    val caojianxi = new Man("caojianxi", 18)
    println(p4.bigger(hulei,caojianxi).name)
  }
}



package com.doit.scala.yinshizhuanhuan

class Man(val name:String,val age:Int) {




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

}

以上的代码都是即将淘汰的方法,下面是两种新方法

 

package com.doit.scala.yinshizhuanhuan

//既不使用视图界定,也不实用上下文界定,但是要实现跟视图界定和上下文界定一样的功能
//视图界定:隐式转换函数或方法
//上下文界定:隐式转换类型
class Pari5[T] {
//使用柯里化,实现类似视图界定的功能
  def bigger(first: T,second: T)(implicit f:T => Ordered[T]):T = {
    if(first>=second)first else second
  }
  //使用柯里化,实现类似上下文界定的功能
  def select(first: T,second: T)(implicit ord: Ordering[T]):T = {
    if(ord.gteq(first,second))first else second
}
}
object Pari5{
  def main(args: Array[String]): Unit = {
    import ContextDemo._
    //    val p5 = new Pari5[Boy]
    //    val hulei = new Boy("hulei", 2)
    //    val caojianxi = new Boy("caojianxi", 100000)
    //    val boy = p5.bigger(hulei, caojianxi)
    //    println(boy.name)

    val p = new Pari5[Man]

    val b1 = new Man("A", 88)
    val b2 = new Man("B", 99)


    val r = p.bigger(b1, b2)

    println(r.name)
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值