泛型(看懂)
<: 上边界限定
先定义类,Animal,Dog(继承Animal),SmallDog(继承Dog)
//只能饲养Dog或者Dog的⼦类 上边界限定
def keepDog[T <: Dog](t:T):Unit={
println(t)
}
def main(args: Array[String]): Unit = {
val animal = new Animal("原始动物")
val dog = new Dog("⼤⻩狗")
val smallDog = new SmallDog("⼩狗狗")
keepDog(dog)
keepDog(smallDog)
keepDog(animal)//错误
}
下边界限定 >:
//只能饲养Dog或者Dog的⽗类 下边界限定 bug
def keepAnimal[T >: Dog](t:T):Unit={
println(t)
}
def main(args: Array[String]): Unit = {
val animal = new Animal("原始动物")
val dog = new Dog("⼤⻩狗")
val smallDog = new SmallDog("⼩狗狗")
keepAnimal(dog)
keepAnimal(animal)
keepAnimal(smallDog)//本不应该成功!但成功了,这⾥我们理解为是个Bug
}
//只允许是Dog或者Dog的⽗类
trait Keeper[T >: Dog] {
def keep(t:T):Unit={
println(t)
}
}
def main(args: Array[String]): Unit = {
val animal = new Animal("原始动物")
val dog = new Dog("⼤⻩狗")
val smallDog = new SmallDog("⼩狗狗")
val k1= new Keeper[Dog] {
override def keep(t: Dog): Unit = {
println(t)
}
}
val k2= new Keeper[Animal] {
override def keep(t: Animal): Unit = {
println(t)
}
}
val k3= new Keeper[SmallDog] { //错误
override def keep(t: SmallDog): Unit = {
println(t)
}
}
}
<% 视图限定
例如 T <% U ,要求上下⽂必须有⼀个 隐式转换 能够将T 转换为 U类型。
class SmallDog(name:String) extends Dog (name:String){
override def speek(): Unit = {
println(s"$name ⼩狗叫~")
}
}
//可以将T看做是⼩狗
def keeperSmallDog[T <% SmallDog](t:T):Unit={
t.speek()
}
object MyImlipcits {
//定义⼀个String -> SmallDog转换
implicit def s2sd(name:String):SmallDog={
new SmallDog(name)
}
}
def main(args: Array[String]): Unit = {
keeperSmallDog(new SmallDog("⼩花花"))
import MyImlipcits._
keeperSmallDog("佩奇")
}
T:A上下文限定
表示上下⽂中环境中必须存在这种隐式值 A[T] 隐式值,否则程序编译出错.这样可以在上下⽂中还没
有隐式值得时候确保⽅法能编译成功。
class Student[T] {
def showMessage(msg:T):Unit={
msg match {
case name:String => println("name:"+name)
case age:Int => println("age:"+age)
case _ => println("不知道")
}
}
}
//上下⽂中 必须得有 Student[T] 类型隐式值
def sayInformation[T:Student](t:T):Unit={
val stu = implicitly[Student[T]]
stu.showMessage(t)
}
def main(args: Array[String]): Unit = {
import MyImlipcits._
sayInformation("zhangsan")
sayInformation(18)
sayInformation(true)
}
object MyImlipcits {
implicit val stu1=new Student[String]
implicit val stu2=new Student[Int]
}
+A协变
//管理T或者T的⼦类 将子类引用赋值给父类
trait Manager[+T] {}
var m1=new Manager[Animal] {}
var m2=new Manager[Dog] {}
var m3=new Manager[SmallDog] {}
m1=m2
m2=m3
m2=m1//错误
将⼦类的泛型引⽤赋值给⽗类。
-A逆变
//管理T或者T的⽗类
trait Manager[-T] {}
var m1=new Manager[Animal] {}
var m2=new Manager[Dog] {}
var m3=new Manager[SmallDog] {}
m1=m2//错误
m2=m3//错误
m2=m1
m3=m1
将⽗类的泛型引⽤赋值给⼦类。
A不变
//管理T
trait Manager[T] {}
var m1=new Manager[Animal] {}
var m2=new Manager[Dog] {}
var m3=new Manager[SmallDog] {}
m1=m2//错误
m2=m3//错误
m2=m1//错误
m3=m1//错误
集合/数组(重点)
Array-数组
//伴⽣对象创建数组
var a1=Array(1,2,3,5,4)
//创建⻓度为5的数组,所有值都是0 ---new 对象的方式创建数组
var a2=new Array[Int](5)
//获取⻓度
a1.length
a2.size
//修改
a1(1) = -1
a1.update(1,-2)
//遍历数组
for(i<- a1) println(i)
Range-区间(只读)
产⽣的是⼀个只读区间和数组类似,但是内容不可以修改。
//创建区间
var r1=new Range(0,10,3) //0 3 6 9 ---new 对象的形式创建区间
var r2=0.to(10).by(3)
var r3=0 until 10 by 3
//取值
r1(2) // 6 可以取值但不可以修改
//r1(2) = 12 //错误
//遍历range
for(i<- r1) println(i)
//⻓度⼤⼩
r1.size
r1.length
Vector-坐标(只读)
//创建向量
var v1= Vector(1,2,3) //工厂apply形式创建
var v2= for(i <- 0 to 10 by 3) yield i
//取值
v1(0) //1 可以取值不可更改
//不⽀持修改
//v1(2) = 12 //错误
//遍历Vector
for(i<- v1) println(i)
//⻓度⼤⼩
v1.size
v1.length
Iterator -游标
不可以根据下标读取,且只能遍历⼀次。
//创建⼀个游标
var it=Iterator(1,2,3) //工厂形式创建
//只可以被遍历⼀次
for(i<- it) println(i)
//计算⼤⼩.将集合清空 不可以根据下标取值
it.size
it.length
//判断是否为空
val flag= it.isEmpty
list不可变集合(重点)
//创建集合
var list=List(1,2,5,3,2)
//添加元素 产⽣新的集合数组,不会修改原始集合
list.::(10)
list.+:(11)
//追加新的集合元素 产⽣新的集合数组,不会修改原始集合
list.:::(List(7,8,9))
//删除n个元素 产⽣新的集合数组,不会修改原始集合
list.drop(3) //List(3, 2)
list.dropRight(3) //List(1, 2)
//删除符合条件的元素,匹配⼀个⽴即终⽌
list.dropWhile(item=> item < 5) // List(5, 3, 2) ---不是必须使用item
//选择⼀个⼦集 从0开始到4不包含4 产⽣新的集合数组,不会修改原始集合
list.slice(0,4)
//前后翻转集合 产⽣新的集合数组,不会修改原始集合
list.reverse // List(2, 3, 5, 2, 1)
//去除重复 产⽣新的集合数组,不会修改原始集合
list.distinct // List(1, 2, 5, 3)
//获取前n个元素 产⽣新的集合数组,不会修改原始集合
list.take(3) //List(1, 2, 5)
list.takeRight(3) //List(5, 3, 2)
//⼀直拿,直到第⼀个不满⾜条件终⽌ 产⽣新的集合数组,不会修改原始集合
list.takeWhile(item => item < 5 ) //List(1, 2)
//获取第⼀个元素、最后⼀个元素、除第⼀个以外的所有元素
list.head
list.last
list.tail
//获取数组⼤⼩
list.size
list.length
//获取数组指定位置的元素
list(2) // 5
ListBuffer 可变集合
//创建集合
var list=ListBuffer(1,2,5,3,2)
//添加元素 产⽣新的集合数组,不会修改原始集合
//list.::(10)
list.+:(11) //ListBuffer(1, 2, 5, 3, 2, 11)
//添加元素 产⽣新的集合数组,修改原始集合
list.+=(-1) // ListBuffer(1, 2, 5, 3, 2, -1)
list.+=:(-2) // ListBuffer(-2,1, 2, 5, 3, 2, -1)
//追加新的集合元素 产⽣新的集合数组,修改原始集合
//list.:::(List(7,8,9))
list.++=(List(7,8,9)) // ListBuffer(1, 2, 5, 3, 2, 7, 8, 9)
list.++=:(List(7,8,9))// ListBuffer(7, 8, 9, 1, 2, 5, 3, 2, 7, 8, 9)
//删除n个元素 产⽣新的集合数组,不会修改原始集合
list.drop(3) //List(3, 2)
list.dropRight(3) //List(1, 2)
//删除符合条件的元素,匹配⼀个⽴即终⽌
list.dropWhile(item=> item < 5) // List(5, 3, 2)
//选择⼀个⼦集 从0开始到4不包含4 产⽣新的集合数组,不会修改原始集合
list.slice(0,4)
//前后翻转集合 产⽣新的集合数组,不会修改原始集合
list.reverse // List(2, 3, 5, 2, 1)
//去除重复 产⽣新的集合数组,不会修改原始集合
list.distinct // List(1, 2, 5, 3)
//获取前n个元素 产⽣新的集合数组,不会修改原始集合
list.take(3) //List(1, 2, 5)
list.takeRight(3) //List(5, 3, 2)
//⼀直拿,直到第⼀个不满⾜条件终⽌ 产⽣新的集合数组,不会修改原始集合
list.takeWhile(item => item < 5 ) //List(1, 2)
//获取第⼀个元素、最后⼀个元素、除第⼀个以外的所有元素
list.head
list.last
list.tail
//获取数组⼤⼩
list.size
list.length
//获取数组指定位置的元素
list(2) // 5
//修改指定位置
list(2) = 12 // ListBuffer(1, 2, 12, 3, 2)
list.update(2,5) //ListBuffer(1, 2, 5, 3, 2)
//删除某个元素 修改原始集合
list.-=(1) // ListBuffer(2, 5, 3, 2)
//删除指定位置元素 修改原始集合
var item=list.remove(2)
//从指定位置 插⼊元素 修改原始集合
list.insert(0,-1,-2) //从0位置插⼊ -1,-2
list.insertAll(0,List(0,0))
Set-不可变(重点)
//创建集合 去重 直接使用工厂类的apply创建
var s=Set[Int](1,2,4,5,3)
//添加⼀个元素 产⽣新的集合Set,不会修改原始集合
s.+(6) //Set(5, 1, 6, 2, 3, 4)
//删除元素 产⽣新的集合Set,不会修改原始集合
s.-(5) // Set(1, 2, 3, 4)
//获取set⼤⼩
s.size
//添加⼀个集合 产⽣新的集合Set,不会修改原始集合
s.++(List(6,6,7)) //Set(5, 1, 6, 2, 7, 3, 4)
//判断元素是否存在
var isExists=s(5) //true 由于set集合没有顺序,直接给值相当于判断元素是否存在
isExists=s(7) //false
Set-可变
//不可用方法依旧可用
import scala.collection.mutable.Set
//创建集合 去重
var s=Set[Int](1,2,4,5,3)
//添加⼀个元素 产⽣新的集合Set,修改原始集合 --add方法新增,改变集合
s.add(6) //Set(5, 1, 6, 2, 3, 4)
//删除元素 产⽣新的集合Set,修改原始集合
s.remove(5) //Set(1, 2, 3, 4) --remove方法新增,改变集合
HashMap-不可变(重点)
import scala.collection.immutable.HashMap
var hm= HashMap[String,String](("建设","001"),("招商","002"))
//添加⼀个元素,并不会修改原始的Map
hm.+("农业","003")
hm.+("⺠⽣"->"004")
//删除元数据,并不会修改原始的Map
hm.-("建设","招商")
//获取指定key的值
val value: Option[String] = hm.get("建设")
val sv1= value.get //该值必须存在
val sv2= value.getOrElse("啥也没有" )
//判断key是否存在
hm.contains("建设")
//更新⼀个key,并不会修改原始的Map
hm.updated("建设","003")
//获取所有keys
val keys = hm.keys
val values = hm.values
//遍历⼀个Map
for(i<- hm.keys){
println(i+" "+hm.get(i).getOrElse(""))
}
//合并两个map
var hm2=HashMap[String,String]("⼯商"->"003",("建设","005"))
//在key出现重复的时候,使⽤t2覆盖t1的元素
hm.merged(hm2)((t1,t2)=> t2)
HashMap-可变
//不可变方法依旧可用
var hm= HashMap[String,String](("建设","001"),("招商","002"))
//添加⼀个元素,修改原始的Map 增加一个put方法,更改原始集合
hm.put("⼯商","005")
//删除元数据,修改原始的Map 增减一个remove方法,更改原始集合
hm.remove("建设")
Java集合和Scala集合相互转换
import scala.collection.JavaConverters._
object TestJavaScalaCollection {
def main(args: Array[String]): Unit = {
val arrayList = new util.ArrayList[String]()
arrayList.add("hello")
arrayList.add("word")
for(i <- 0 until arrayList.size()){
println(arrayList.get(i))
}
val scalaList = arrayList.asScala
for(i<- scalaList){
println(i)
}
val javaList = scalaList.asJava
for(i <- 0 until javaList.size()){
println(javaList.get(i))
}
}
}