泛型方法

把泛型定义到方法声明上,该方法参数由泛型由泛型决定
在调用时,明确类型

  1. // 不采用泛型
  2. def getMiddleElement(arr: Array[Any]) = arr(arr.length/2)
  3. // 采用自定义泛型
  4. def getMiddleElement[T](arr: Array[T]) = arr(arr.length /2)
  5. def main(args: Array[String]): Unit = {
  6. println(getMiddleElement(Array(1, 2, 3, 4, 5)))
  7. println(getMiddleElement(Array("a", "b", "c")))
  8. }

泛型类

把泛型定义到类的声明上,即该类中的成员的参数由泛型决定
在创建对象时,明确具体数据类型

  1. class Pair[T](var a: T, var b: T)
  2. def main(args: Array[String]) = {
  3. val p1 = new Pair[Int](10, 20)
  4. println(p1.a, p1.b)
  5. }

泛型特质

在定义泛型特质的子类或者子类单例对象时,明确具体的数据类型

  1. trait Logger[T] {
  2. val a: T
  3. def show(b:T)
  4. }
  5. object ConsoleLogger extends Logger[String] {
  6. override val a: String = "xxx"
  7. override def show(b: String): Unit = println(b)
  8. }
  9. def main(args:Array[String]): Unit = {
  10. println(ConsoleLogger.a)
  11. ConsoleLogger.show("abc")
  12. }

协变 逆变 非变

  • 非变:AB父子类关系,Pair[A] Pair[B]之间没有关系
  • 协变:AB父子类关系,Pair[A] Pair[B]之间也是父子关系
  • 逆变:AB父子类关系,Pair[A] Pair[B]之间是 子 父 关系 ```scala class Super class Sub extends Super class Temp1[T] class Temp2[+T] class Temp3[-T]

def main(args: Array[String]): Unit = { // 非变 val t1: Temp1[Sub] = new Temp1[Sub] val t2: Temp1[Super] = t1 //报错 非变 Super和Sub有父子类关系,但是Temp1[Super]和Temp1[Sub]没有关系

// 协变 val t3: Temp2[Sub] = new Temp2[Sub] val t4: Temp2[Super] = t3 // 协变

//逆变 val t5: Temp3[Sub] = new Temp3[Sub] val t6: Temp3[Super] = t5 // 报错

val t7: Temp3[Super] = new Temp3[Super] val t8: Temp3[Sub] = t7 }

  1. ```scala
  2. object Test {
  3. def main(args: Array[String]): Unit = {
  4. val child: Parent = new Child
  5. val childList: MyCollection[Parent] = new MyCollection[Child]
  6. }
  7. }
  8. class Parent {}
  9. class Child extends Parent {}
  10. class SubChild extends Child{}
  11. // 定义带泛型的集合类型
  12. class MyCollection[+E] {} //协变 -E是逆变

泛型上下限

使用泛型时,如果要限定该泛型必须从哪个类继承,或者必须是哪个类的的父类,就需要使用泛型上下界

上界

[T <: Person] 只能是Person类型或者Person的子类

  1. class Person
  2. class Student extends Person
  3. // 限定demo方法的Array元素类型只能是Person或者Person子类
  4. def demo[T <: Person](arr: Array[T]): Unit = println(arr)
  5. def main(args: Array[String]): Unit = {
  6. demo(Array(new Person(), new Person()))
  7. }

下界

必须是该类型或者该类型的父类型

  • 同时有上下界时,[T >: 类型1 <: 类型2] 下界在前,上界在后 ```scala class Person

class Policeman extends Person

class Superman extends Policeman

def demoT >: Policeman = println(arr)

def main(arrs: Array[String]): Unit = { demo(Array(new Person())) demo(Array(new Policeman(), new Policeman())) demo(Arrau(new Superman())) //error }

  1. ```scala
  2. def test[A <: Child](a: A): Unit = {
  3. println(a.getClass.getName)
  4. }
  5. test[Parent](new Child) // 报错,相当于把Child对象赋给了Parent类型的指针
  6. test[Child](new Child)
  7. test[Child](new subChild)

案例:列表排序去重

  1. 11
  2. 22
  3. 44
  4. 55
  5. 66
  6. 77
  7. 88
  1. object Test02 {
  2. def main(args: Array[String]): Unit = {
  3. val file = Source.fromFile("./conf/test02")
  4. // 将数据按照空白字符切割 -> 数组类型 -> 列表类型
  5. val list1: List[String] = file.mkString.split("\\s+").toList
  6. val list2: List[Int] = list1.map(_.toInt)
  7. val set: Set[Int] = list2.toSet
  8. val list3: List[Int] = set.toList.sorted
  9. val bw = new BufferedWriter(new FileWriter("./conf/test03"))
  10. for(i <- list3) {
  11. bw.write(i.toString)
  12. bw.newLine()
  13. }
  14. bw.close()
  15. file.close()
  16. }
  17. }