深圳大数据学习:泛型 --【千锋】

带有一个或多个类型参数的类是泛型的。
泛型类的定义:
//带有类型参数A的类定义
class Stack[A] {
private var elements: List[A] = Nil
//泛型方法
def push(x: A) { elements = x :: elements }
def peek: A = elements.head
def pop(): A = {
val currentTop = peek
elements = elements.tail
currentTop
}
}
泛型类的使用,用具体的类型代替类型参数A。
val stack = new Stack[Int]
stack.push(1)
stack.push(2)
println(stack.pop) // prints 2
println(stack.pop) // prints 1
8.1.协变
定义一个类型List[+A],如果A是协变的,意思是:对类型A和B,A是B的子类型,那么List[A]是List[B]的子类型。
abstract class Animal {
def name: String
}
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal
Scala标准库有一个泛型类sealed abstract class List[+A],因为其中的类型参数是协变的,那么下面的程序调用时成功的。
object CovarianceTest extends App {
//定义参数类型List[Animal]
def printAnimalNames(animals: List[Animal]): Unit = {
animals.foreach { animal =>
println(animal.name)
}
}

val cats: List[Cat] = List(Cat(“Whiskers”), Cat(“Tom”))
val dogs: List[Dog] = List(Dog(“Fido”), Dog(“Rex”))
//传入参数类型为List[Cat]
printAnimalNames(cats)
// Whiskers
// Tom
//传入参数类型为List[Dog]
printAnimalNames(dogs)
// Fido
// Rex
}
8.2.逆变
定义一个类型Writer[-A],如果A是逆变的,意思是:对类型A和B,A是B的子类型,那么Writer[B]是Writer[A]的子类型。
abstract class Animal {
def name: String
}
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal
定义对应上述类进行操作的打印信息类
abstract class Printer[-A] {
def print(value: A): Unit
}
class AnimalPrinter extends Printer[Animal] {
def print(animal: Animal): Unit =
println("The animal’s name is: " + animal.name)
}

class CatPrinter extends Printer[Cat] {
def print(cat: Cat): Unit =
println("The cat’s name is: " + cat.name)
}
逆变的测试
object ContravarianceTest extends App {
val myCat: Cat = Cat(“Boots”)

//定义参数类型为Printer[Cat]
def printMyCat(printer: Printer[Cat]): Unit = {
printer.print(myCat)
}

val catPrinter: Printer[Cat] = new CatPrinter
val animalPrinter: Printer[Animal] = new AnimalPrinter

printMyCat(catPrinter)
//可以传入参数类型为Printer[Animal]
printMyCat(animalPrinter)
}
8.3.上界
上界定义: T <: A ,表示类型变量T 必须是 类型A 子类
abstract class Animal {
def name: String
}

abstract class Pet extends Animal {}

class Cat extends Pet {
override def name: String = “Cat”
}

class Dog extends Pet {
override def name: String = “Dog”
}

class Lion extends Animal {
override def name: String = “Lion”
}
//参数类型须是Pet类型的子类
class PetContainer[P <: Pet](p: P) {
def pet: P = p
}
//Dog是Pet类型的子类
val dogContainer = new PetContainer[Dog](new Dog)
//Cat是Pet类型的子类
val catContainer = new PetContainer[Cat](new Cat)
//Lion不是Pet类型的子类,编译通不过
// val lionContainer = new PetContainer[Lion](new Lion)
8.4.下界
语法 B >: A 表示参数类型或抽象类型 B 须是类型A的父类。通常,A是类的类型参数,B是方法的类型参数。

上面这段代码,因为作为协变类型的B,出现在需要逆变类型的函数参数中,导致编译不通过。解决这个问题,就需要用到下界的概念。
trait Node[+B] {
def prepend[U >: B](elem: U): Node[U]
}

case class ListNode[+B](h: B, t: Node[B]) extends Node[B] {
def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this)
def head: B = h
def tail: Node[B] = t
}

case class Nil+B extends Node[B] {
def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this)
}
测试
trait Bird
case class AfricanSwallow() extends Bird
case class EuropeanSwallow() extends Bird

val africanSwallowList= ListNode[AfricanSwallow](AfricanSwallow(), Nil())
val birdList: Node[Bird] = africanSwallowList
birdList.prepend(new EuropeanSwallow)
8.5 视界(view bounds)
注意:已过时,了解即可
视界定义: A <% B ,表示类型变量A 必须是 类型B`的子类,或者A能够隐式转换到B
class Pair_Int[T <% Comparable[T]] (val first: T, val second: T){
def bigger = if(first.compareTo(second) > 0) first else second
}

class Pair_Better[T <% Ordered[T]](val first: T, val second: T){
def smaller = if(first < second) first else second
}
object View_Bound {

def main(args: Array[String]) {
// 因为Pair[String] 是Comparable[T]的子类型, 所以String有compareTo方法
val pair = new Pair_Int(“Spark”, “Hadoop”);
println(pair.bigger)

/*** Scala语言里 Int类型没有实现Comparable;* 那么该如何解决这个问题那;* 在scala里 RichInt实现了Comparable, 如果我们把int转换为RichInt类型就可以这样实例化了.* 在scala里 <% 就起这个作用, 需要修改Pair里的 <: 为<% 把T类型隐身转换为Comparable[Int]* String可以被转换为RichString. 而RichString是Ordered[String] 的子类.*/
val pair_int = new Pair_Int(3 ,45)
println(pair_int.bigger)val pair_better = new Pair_Better(39 ,5)
println(pair_better.smaller)

}

}
8.6 上下文界定(context bounds)
上下文界定的形式为 T : M, 其中M 必须为泛型类, 必须存在一个M[T]的隐式值.
class Pair_Context[T : Ordering](val first: T, val second: T){
def smaller(implicit ord: Ordering[T]) =
if(ord.compare(first, second) < 0) first else second
}

object Context_Bound {

def main(args: Array[String]) {

val pair = new Pair_Context("Spark", "Hadoop")
println(pair.smaller)val int = new Pair_Context(3, 5)
println(int.smaller)

}

}

深圳大数据学习:泛型 --【千锋】相关推荐

  1. 深圳大数据学习:方法的嵌套--【千锋】

    深圳大数据学习:方法的嵌套–[千锋] 方法里嵌套定义其他方法 示例1 object EmbedDemo { def add3(x:Int,y:Int,z:Int)={ def add2(x:Int,y ...

  2. 深圳大数据学习:高阶函数--【千锋】

    深圳大数据学习:高阶函数–[千锋] 1.1. 概念 如果一个函数的传入参数为函数或者返回值是函数,则该函数即为高阶函数. 1.2. 传入参数为函数 Scala中,函数是头等公民,和数字一样.不仅可以调 ...

  3. 深圳大数据学习:Scala系列之文件以及正则表达式

    深圳大数据学习:Scala系列之文件以及正则表达式 7.1 读取行 导入scala.io.Source后,即可引用Source中的方法读取文件信息. import scala.io.Source ob ...

  4. 深圳大数据培训:好程序员大数据学习路线之hive 存储格式

    深圳大数据培训:好程序员大数据学习路线之hive 存储格式 好程序员大数据学习路线之hive存储格式,hive的存储格式通常是三种:textfile . sequencefile . rcfile . ...

  5. 深圳爱思拓大数据 网站_建议收藏!13个大数据学习网站很少人知道!附大数据自学资料分享...

    数据分析重要性 越来越多的管理者意识到数据分析对经济发展.企业运营的重要意义 在古代,得琅琊阁者得天下 现在,得大数据者得天下 我总结的数据分析五步走: 1.锁定分析目标,梳理思路,叫纸上谈兵: 2. ...

  6. 大数据学习路线2019版(附全套视频教程及网盘下载)

    什么是大数据? 大数据(BIG DATA)是指无法在一定时间范围内用常规软件工具进行捕捉.管理和处理的数据集合,是需要新处理模式才能具有更强的决策力.洞察发现力和流程优化能力的海量.高增长率和多样化的 ...

  7. 深圳大数据培训技术分享:Hadoop集群同步

    深圳大数据培训技术分享:Hadoop集群同步 分享--是技术突飞猛进的很好体验!在千锋学习大数据技术,开始学会了分享,班里五十个人,每个人就能得到49份不同技术探讨.每次到分享的时刻,总会收获不同的想 ...

  8. 深圳大数据培训:大数据技术可以解决哪些问题?

    深圳大数据培训:大数据技术可以解决哪些问题? 去年,大数据专业成为很多高校爆款专业,比如复旦,中南等.为什么如此多的大学开设此专业?学习它之后能解决哪些问题?以后它会应用在哪些工作岗位上? 一. 为什 ...

  9. “华为云杯”2020深圳开放数据应用创新大赛线上推介会成功举办,让深圳大数据在全球“跑”起来...

    4月30日下午,"华为云杯"2020深圳开放数据应用创新大赛第三场线上推介会完美落幕.至此,从4月23日开始的三场云端推介会全部结束,全球各数字平台总观看量1000多万人次.深圳市 ...

最新文章

  1. 过滤器在图纸上的符号_终于找全了,施工图纸上那一堆难记的符号,赶紧收藏!...
  2. ubuntu16.04无法连接WiFi搜索不到网络网卡驱动
  3. Mybatis逆向工程的pojo实现序列化接口的代码
  4. java enum枚举使用例子
  5. JS实现的一个验证码,可以在前端验证后在提交action
  6. 我常用的Latex中文报告模板(一)
  7. 自动排单功能的一些思考
  8. 新数据时代,浪潮存储如何革故鼎“新”
  9. 计算机自主招生证书,高校自主招生必备常识:五大学科竞赛证书含金量
  10. thymeleaf中数字的日期格式以及货币格式
  11. html实现波浪,纯CSS实现波浪移动效果的示例
  12. [AV1] AV1 Video Codec
  13. 关于放大器失真的原因你了解多少呢?
  14. 无锡:车联网先导区“排头兵”,编织的自动驾驶产业雄心!
  15. C语言程序设计-算数运算符、赋值运算符、逗号运算符及表达式
  16. VMware共享文件夹设置
  17. 哈佛《幸福课》 第1课 什么是积极心理学
  18. Android数据加密DES、3DES、AES
  19. Web自动化——Selenium原理
  20. uniapp扫描身份证获取信息

热门文章

  1. 查询本机ip地址快捷键
  2. 连接Linux服务器下Oracle数据库提示:ORA-12541: TNS: 无监听程序
  3. 自动化运维平台功能大纲
  4. python编程中出现“Process finished with exit code 1073741845”
  5. CloudEvents 入门文档
  6. 徐州初中计算机学校排名2015,徐州市十大重点初中排名
  7. 东营初中计算机成绩,东营市初中排名前十
  8. 幸福是一种能力读后感_我分析了736天的幸福感。 这是我学到的。
  9. sql server查询不显示结果_仅凭网上查询结果显示邮件由行政机关签收,能证明行政机关一定收到了当事人的申请吗?...
  10. DiscuzX3.4论坛火车头采集器免登陆发布模块(带测试接口)