一、类型参数
泛型类代码:
package generic /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @date : 2020/11/19 * @time : 7:54 下午 * Scala的类型参数学习:Scala的类型参数和Java一样,既可以定义在类上面,也可以定义在方法上面 * Java中的泛型定义,使用<>,<>指定具体的泛型,使用大写的标识符来制定,通常是大写字母,可以是一个字母,也可以是多个字母 * Scala中的泛型定义使用[],[]指定具体的泛型,使用大写的标识符来制定,通常是大写字母,可以是一个字母,也可以是多个字母 * * 泛型类:所谓泛型类就是在类上面定义一个泛型,我们可以把这个泛型当成是类的一个成员,在类的作用域范围内进行使用, * 可以在成员变量,成员方法上面来使用这个泛型 * */ object GenericTypeOps1 { def main(args: Array[String]): Unit = { val userController = new UserController userController.register(User("alex",21)) } } // 构建用户user,完成网络注册的业务逻辑 case class User(name:String,age:Int) case class Product(pid:Long,name:String,price:Float) trait BaseDao[T]{ // 通用的泛型保存方法 def insert(item:T) } // 具体实现类--用户 class UserDao extends BaseDao[User]{ override def insert(item: User): Unit = { println(s"向数据库插入用户信息为: ${item.name}\t${item.age}") } } // 具体实现类--商品 class ProductDao extends BaseDao[Product]{ override def insert(item: Product): Unit = { println(s"向数据库插入商品信息为: ${item.pid}\t${item.name}\t${item.price}") } } // 用户的业务层逻辑 class UserServiceImpl{ val userDao = new UserDao def save(user: User): Unit ={ userDao.insert(user) } } class UserController{ val us = new UserServiceImpl def register(user: User): Unit ={ us.save(user) } }
运行结果:
向数据库插入用户信息为: alex 21
scala泛型的协变和逆变
package generic /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @date : 2020/11/20 * @time : 11:45 上午 * * 在Java中泛型的一个基本特点:"="左右两侧的泛型类型,必须一致,不可以出现左右两侧的泛型有继承的关系 * * scala泛型的协变和逆变 * 在默认情况下,Scala中的"="左右两侧的泛型类型关系和Java中是一致,不能允许出现继承关系, * 但是Scala我们可以来修订这个相等的关系 */ object GenericOps { def main(args: Array[String]): Unit = { val myList:MyList[Person] = new MyList[Person] val myList1:MyList1[Person] = new MyList1[Person] val myList2:MyList2[Person] = new MyList2[Person] } } class Person{ } class Student extends Person{ } class Worker extends Person{ } class MyList[T]{ } class MyList1[+T]{ // 泛型的协变 } class MyList2[-T]{ // 泛型的逆变 }
二、隐式转换
package implicits /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @date : 2020/11/20 * @time : 1:08 下午 * 隐式转换:所谓隐式转换就是将一种类型转换成另外一种类型,并且这个转换的操作不是显示执行,而是隐式执行 * 实现这个操作背后的力量——隐式转换 * * 隐式转换函数:是一个特别的函数,必须有参数,有返回值,其次还要被关键字implicit所修饰 * 常见的定义格式如下: * implicit def source2Target(source:Source):Target = { * //... * } */ object ImplicitOps1 { def main(args: Array[String]): Unit = { val x:Int = 3 val y:Int = 3.5f val z:Int = "abcfdf" println("x:" + x) println("y:" + y) println("z:" + z) } implicit def float2Int(float: Float): Int ={ float.intValue() } implicit def str2Int(string: String): Int ={ string.length } }
运行结果:
x:3 y:3 z:6
scala隐式转换功能之丰富现有API的类库
package implicits import java.io.{File, FileWriter} import scala.io.Source /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @date : 2020/11/20 * @time : 1:23 下午 * scala隐式转换功能之丰富现有API的类库 * 让Java.io.File类具备读写文件的能力 */ object ImplicitOps2 { def main(args: Array[String]): Unit = { val file:File = new File("data/wordcount.txt") val filename = file.getName println("filename: " + filename) println("-----------file.read------------") val lines = file.read() for (line <- lines){ println(line) } println("-----------file.write------------") file.write("\r\nhello spark") } implicit def file2RichFile(file: File): RichFile = { new RichFile(file) } class RichFile(file: File) { def read() = Source.fromFile(file).getLines().toList def write(string: String): Unit ={ val bw = new FileWriter(file,true) bw.write(string) bw.flush() bw.close() } } }
运行结果:
-----------file.read------------ java python java java hadoop php hive sqoop spark linux shell hello spark -----------file.write------------
scala隐式转换的导入
package implicits import java.io.File import ImplicitOps2._ /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @date : 2020/11/20 * @time : 2:45 下午 * 其一,scala隐式转换的导入有点类似导包 * 其二,只需要将我们该隐式转换引入到相关变量的作用域范围内即可 * 其三,该变量就会自动在其作用域范围内去检索被implicit关键字修饰的函数 * 其四,当找到implicit对应的函数有多个时候,就会根据自己的类型和返回值的类型,进行匹配, * 一次来确定到底要是用哪一个隐式转换 * 注意:只需要我们做导包,不需要进行强制的指定 */ object ImplicitOps3 { def main(args: Array[String]): Unit = { val file:File = new File("data/wordcount.txt") for (line <- file.read()){ println(line) } } }
运行结果:
java python java java hadoop php hive sqoop spark linux shell hello spark hello spark
Scala隐式转换参数
package implicits /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @date : 2020/11/20 * @time : 5:05 下午 * Scala隐式转换参数 * 也就是说一个函数的参教被implicit关键宇修饰,把这些参数称之为隐式转换参数。 * 首先,该参数,不一定非得要(手动,显示)传递(赋值),因为有时候有默认值 * 其次,该参数,会自动的在其作用域范围内进行检索,找到相适应的变量,来完成赋值, * 需要注意的是,该变量必须要被implicit关键字进行修饰 */ object ImplicitOps4 { def main(args: Array[String]): Unit = { var array = Array(3,5,12,2,5,7,-4,-2) println("排序前的数组" + array.mkString("[",",","]")) // 排序 var newArr = array.sortWith(_ < _) println("排序后的数组" + newArr.mkString("[",",","]")) println("---------------sorted---------------") implicit val ord = new Ordering[Int](){ override def compare(x: Int, y: Int): Int = y.compareTo(x) } newArr = array.sorted println("排序后的数组" + array.sorted.mkString("[",",","]")) } }
排序前的数组[3,5,12,2,5,7,-4,-2] 排序后的数组[-4,-2,2,3,5,5,7,12] ---------------sorted--------------- 排序后的数组[12,7,5,5,3,2,-2,-4]