scala的泛型

82 阅读3分钟

(一)问题导入

需求定义一个名为getMiddleElement的方法,用它来获取输入列表的中间位置上的元素。以整型数据为例,我们可以写代码如下

def main(args: Array[String]): Unit = {  
  val arr1 = Array(1,2,3,4,5)  
  def getMiddleEle(arr:Array[Int]): Int = {  
    arr(arr.length/2)  
  }  
  val i:Int = getMiddleEle(arr1)  
  println(i)  
}

新的需求:如果来了一个新的列表,它保存的是字符串类型的列表,大家应该如如何去实现这个功能呢?

可以改下函数,把函数换个名字吗? 当然可以的,但是,这样就太浪费了。

此时我们遇到的困难是: 类型是变化的!

这里就可以使用泛型改进:使用泛型来定义。

/*
* 定一个名为getMiddle方法 用来获取输入列表的中间位置上的元素
* */
//两个函数长的一样!!!只有参数的类型不同。
/*
* 定一个名为getMiddle方法,用来获取传入列表中的中间位置上的元素
* 1 2 3 4 5 6 7
*/
object fx01 {
  def getMiddle(arr:Array[Int]):Int = {
    arr(arr.length/2)
  }

  def getMiddle(arr:Array[String]):String = {
    arr(arr.length/2)
  }

  def main(args: Array[String]): Unit = {
    val arr1 = Array(1,2,3,4,5,6,7)
    println(s"arr1的中间元素是:${getMiddle[Int](arr1)}")

    val arr2 = Array("a","b","c")
    println(s"arr2的中间元素是:${getMiddle[String](arr2)}")

    val arr3 = Array(1,2,2,3,3)
    println(s"arr3的中间元素是:${getMiddle[Int](arr3)}")
  }
}

(二)泛型的概念

泛型的定义为:参数化类型,即所有操作的数据类型被指定为一个参数。

在Scala中,用[]表示(在java中使用<>)。

泛型是对数据的类型的约束!

(三)泛型方法

泛型方法指的是:把泛型定义放在方法声明上。即:该方法的参数类型是由泛型来决定的。在调用方法时,明确具体的数据类型。

(四)泛型方法的格式

定义方法def 方法名[泛型名称1,泛型名称2,. . .](参数列表 ) = {  }

调用方法 方法名[类型1,类型2,](参数列表)

object fx02 {
  //泛型类
  class Ractangle[X](var w:X,var h:X) {
    def getArea():Unit = {
      println(w,h)
    }
  }

  def main(args: Array[String]): Unit = {
    val r1 = new Ractangle[Double](1.5,20)
    r1.getArea()
  }
}

//运行结果:
(1.5,20.0)

如果在参数列表中可以推断出对应的类型,则可以省略方括号[类型1,类型2]

使用泛型方法来解决本课开头提出的问题。

(五)理解泛型

1、泛型和数据类型有什么区别?

case class Student()

val s1 = Student()

val list = ArrayList[Student]()

list += s1

ArrayList 是数据类型,Student是泛型。 他们不是一个层次的概念。 类型内部的数据使用泛型来约束。

2、泛型的声明方式是从外部把类型传入到类的内部,好比是传入参数一样。所以,泛型也称之为类型参数。如果参数没有传递,就说明不需要类型的约束,它也不会发生错误。而是采用通用类型。

3、在编译时有效,在运行时会失效。也就是说在代码被编译之后,在产生的代码中是看不到泛型相关的代码的。