版权声明:本文为博主原创文章,未经博主允许不得转载。 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
}
}
}
柯里化的方式: