Scala的泛型和集合

泛型(看懂)

<: 上边界限定

先定义类,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))
        }
    }
}

猜你喜欢

转载自blog.csdn.net/origin_cx/article/details/104339857