Scala之集合

目录

一、集合简介

二、数组

1.不可变数组

2.可变数组

3.不可变数组与可变数组以及Set的转换

4.多维数组

三、Seq集合

1.不可变List

2.可变ListBuffer

四、Set集合

1.不可变Set

2.可变Set

五、Map集合

1.不可变集合

2.可变集合

六、元组

七、队列

八、并行集合

一、集合简介

(1)Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。

(2)对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本,分别位于以下两个包。

不可变集合:scala.collection.immutable

可变集合:  scala.collection.mutable

(3)不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于java中的String对象

(4)可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于java中StringBuilder对象

注:Scala中的List与Java中的List是不同的概念。

二、数组

1.不可变数组

定义:val arr = new Array[Int](10)

(1)new是关键字

(2)[Int]是指定可以存放的数据类型,如果希望存放任意数据类型,则指定Any

(3)(10),表示数组的大小,确定后就不可以变化
        scala中的不可变数组array是为了和java的[]数组进行对应,所以具有同样的特性,长度不可变但是内容可以修改。(本质调用伴生对象的apply方法)

  def main(args: Array[String]): Unit = {
    //静态定义不可变数组
    val ints1: Array[Int] = Array(1,2,3,4,5)
    //动态定义数组 动态构建里面的元素全部为初始值 例如int就是0
    val ints2: Array[Int] = new Array[Int](6)
    //修改 使用apply方法
    ints2(0) = 1
    //使用update方法
    ints2.update(1,66)
    //循环打印
    for (elem <- ints2) {
      println(elem)
    }
    //迭代器打印
    val iterator: Iterator[Int] = ints2.iterator
    while (iterator.hasNext){
      println(iterator.next())
    }
    //定义函数打印方法
    def myPrint(i :Int): Unit = println(i * 2 + 5)
    ints2.foreach(myPrint)

    ints2.foreach((i :Int) => println(i * 2 + 5))
    ints2.foreach(i => println(i * 2 + 5) )
    //常规方法
    ints2.foreach(println)

    //输出
    println(ints1.toList)
    println(ints2.toList)

    // 因为是不可变,不会修改原数组 会在新生成的数组上改变 
    val ints3: Array[Int] = ints2 :+ 5
    println(ints2.toList)
    println(ints3.toList)
  }

2.可变数组

val arr = ArrayBuffer[Any](5, 7, 9,3)

(1)[Any]存放任意数据类型

(2)(5, 7, 9,3)初始化好的四个元素

(3)ArrayBuffer需要引入scala.collection.mutable.ArrayBuffer

  def main(args: Array[String]): Unit = {
    //填写的数字是底层存储的初始长度  => 默认是16
    //数组的长度只和里面存储元素的个数有关
    val ints: ArrayBuffer[Int] = new ArrayBuffer[Int]()
    //计算数组长度
    val length: Int = ints.length
    println(length)
    //使用apply方法创建
    val buffer: ArrayBuffer[Any] = ArrayBuffer(1,2,3,"ls")
    buffer.foreach(println)
    //添加元素
    buffer.append(4)

    buffer :+ 5 //:+ 即使是可变集合也加不进去元素
    buffer.foreach(println)
    buffer += 5 //可以加进去
    buffer.foreach(println)
    //可以添加多个元素
    buffer.append(20, 30, 40)
    println(buffer)
    //在数组第一个位置添加元素
    buffer.prepend(0)
    println(buffer)
    //数组的合并
    buffer.appendAll(Array(3, 4, 5))
    println(buffer)
    //删除数组
    buffer.remove(1, 2)
    println(buffer)
    // 修改查看,建议使用apply方法
    println(buffer(0))
    buffer.update(1, 100)
    println(buffer)
    buffer(1) = 200
    println(buffer)
    
  }

3.不可变数组与可变数组以及Set的转换

        arr1.toBuffer  //不可变数组转可变数组

        arr2.toArray  //可变数组转不可变数组

         arr1.toSet //转化为Set集合

(1)arr2.toArray返回结果才是一个不可变数组,arr2本身没有变化

      (2)arr1.toBuffer返回结果才是一个可变数组,arr1本身没有变化

  // 可变数组和不可变数组的转换
    val array: Array[Int] = Array(1, 2, 3, 1, 2, 3)
    val arrayBuffer: ArrayBuffer[Int] = ArrayBuffer(4, 5, 6)
    // 不可变数组转换为可变数组
    val buffer2: mutable.Buffer[Int] = array.toBuffer
    // 可变转换为不可变数组
    val array1: Array[Int] = arrayBuffer.toArray
    println(array.toList) //List(1, 2, 3, 1, 2, 3)
    println(arrayBuffer) //ArrayBuffer(4, 5, 6)
    println(buffer2) //ArrayBuffer(1, 2, 3, 1, 2, 3)
    println(array1.toList) //List(4, 5, 6)

    val set1: Set[Int] = array.toSet
    val set2: Set[Int] = arrayBuffer.toSet
    println(set1) //Set(1, 2, 3)
    println(set2) //Set(4, 5, 6)

4.多维数组

创建方法:

1.val array: Array[Array[Int]] = new Array[Array[Int]](4)

2.val arrayDim: Array[Array[Int]] = Array.ofDim[Int](3, 4)

  def main(args: Array[String]): Unit = {
    val array: Array[Array[Int]] = new Array[Array[Int]](4)

    array(0) = Array(1, 2, 3, 4)
    array(1) = Array(1, 2, 3, 4)
    array(2) = Array(1, 2, 3, 4)
    array(3) = Array(1, 2, 3, 4)

    for (elem <- array) {
      for (elem01 <- elem) {
        print(elem01 + "\t")
      }
      println()
    }

    val array1: Array[Array[Int]] = Array.ofDim(3, 4)
    array1(0)(0) = 250
    for (elem <- array1) {
      for (elem01 <- elem) {
        print(elem01 + "\t")
      }
      println()
    }


  }

三、Seq集合

1.不可变List

(1)List默认为不可变集合

(2)创建一个List(数据有顺序,可重复)
(3)遍历List

(4)List增加数据

(5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化
(6)取指定数据
(7)空集合Nil

操作举例:

  def main(args: Array[String]): Unit = {
    // List默认为不可变集合
    // 创建一个List(数据有顺序,可重复)
    // list无法使用new 来创建  => 因为他是一个不可变list,导致里面的元素值也不能修改
    // 所以new创建出来如果都是0,不能修改,因此没法使用
    val ints: List[Int] = List(1,2,3,4)

    ints.foreach(println)
    println(ints)
    //增加数据
    val ints2 = ints :+ 5
    println(ints2)
    //头插
    val ints3: List[Int] = 6 :: ints
    println(ints3)
    //扁平化
    val ints4: List[Int] = List(7,8,9)
    val ints5: List[Any] = ints :: ints4
    println(ints5)  //List(List(1, 2, 3, 4), 7, 8, 9)
    //扁平化类似于sql中的炸裂函数  将一个集合查分为多个单个的元素放入
    val ints6: List[Int] = ints ::: ints4
    println(ints6) //List(1, 2, 3, 4, 7, 8, 9)

    //取元素 不可以修改元素
    val i: Int = ints6(0)
    println(i)

    //Nil空集合
    val ints7: List[Int] = 1 :: 2 :: 3 :: Nil
    println(ints7)
  }

2.可变ListBuffer

(1)创建一个可变集合ListBuffer

(2)向集合中添加数据

(3)删除元素

(4)查看元素

(5)修改元素

操作举例:

  def main(args: Array[String]): Unit = {
    val ints: ListBuffer[Int] = new ListBuffer[Int]()

    val ints1: ListBuffer[Int] = ListBuffer(1,2,3,4)
    //添加
    ints1.append(5)
    //删除
    ints1.remove(1)
    println(ints1)
    //查看
    val i: Int = ints1(1)
    println(i)
    //修改
    ints1(2) = 250
    println(ints1)
  }

四、Set集合

1.不可变Set

(1)Set默认是不可变集合

(2)数据无序不可重复

(3)默认使用hashset

def main(args: Array[String]): Unit = {
    val set: Set[Int] = Set(1,2,3,4,5,6,7)
    //set的特性 无序 不可重复
    println(set)//Set(5, 1, 6, 2, 7, 3, 4)
    // 默认使用hashset,当元素小于等于4个时,会进行特殊的优化(从小到大顺序排序)
    println(set.isInstanceOf[HashSet[Int]])

    val ints = Set(4,5,6,4,8,9,8,1,2,4,1)
    println(ints) //Set(5, 1, 6, 9, 2, 8, 4)
    //添加
    val ints2: Set[Int] = ints + 20
    println(ints2) //Set(5, 20, 1, 6, 9, 2, 8, 4)
    
  }

2.可变Set

        创建可变集合mutable.Set

val ints = Set(4,5,6,4,8,9,8,1,2,4,1)
    println(ints) //Set(5, 1, 6, 9, 2, 8, 4)
    //添加
    val ints2: Set[Int] = ints + 20
    println(ints2) //Set(5, 20, 1, 6, 9, 2, 8, 4)

    val ints3: mutable.Set[Int] = mutable.Set(2,5,7,6,2,3,1,1)
    println(ints3)

    // 可变set能够添加元素,添加的元素一样没有顺序
    ints3.add(20)
    println(ints3)
    val bool: Boolean = ints3.add(30) //true 不存在30 可添加
    println(bool)
    // 判断set中是否存在元素
    val bool1: Boolean = ints3.contains(30)
    println(bool1)

五、Map集合

        Scala中的Map也是一个散列表,存储的内容也是键值对(key-value)映射

1.不可变集合

def main(args: Array[String]): Unit = {
    val map1: Map[String, Int] = Map("hi" -> 1,"hello" -> 2)
    println(map1)
    val map2: Map[String, Int] = Map(("hi",1),("hello",2))
    println(map2)

    // 不可变map内容不能修改,也不能添加元素,只可以读取

    for (elem <- map2) {
      val key: String = elem._1
      val value: Int = elem._2
      println("key:" + key + "\t" + "value:" + value)
    }

    val keys: Iterable[String] = map2.keys
    val values: Iterable[Int] = map2.values
    println(keys.toList)
    println(values.toList)

    // 通过key获取value
    // 避免空值异常 如果获取的key不存在  value为任意类型  可以为数值类型
    // 数值类型不能使用null值表示  需要使用Option表示
    // option用于封装数据  代替null值,  如果数值存在 使用some子类表示 如果不存在使用None表示
    val option: Option[Int] = map2.get("hello01")
    println(option) //None

    if(!option.isEmpty){
      val value1 :Int = option.get
      println(value1)
    }

    //使用ption优化的方法
    val i: Int = option.getOrElse(10) //如果没有 就返回10
    println(i)

    val j: Int = map2.get("hello").getOrElse(10)
    println(j)
    // 如果有值  获取值作为返回结果  如果没有值  使用第二个参数作为默认值
    val i1: Int = map2.getOrElse("hello",0)
    println(i1)

    //使用apply方法读取 
    val i2: Int = map2("hello")
    println(i2)

  }

2.可变集合

 val map3: mutable.HashMap[String, Int] = new mutable.HashMap[String,Int]()

    val map4: mutable.Map[String, Int] = mutable.Map(("hi",1),("hello",2))

    //添加
    //如果存在会修改value值  如果不存在会添加元素
    map4.update("nihao",3)
    println(map4)
    map4.put("nihao",5)
    println(map4)
    //使用apply
    map4("nihao") = 100
    println(map4)
    //删除
    map4.remove("nihao")
    println(map4)

六、元组

        元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。

        注意:元组中最大只能有22个元素。

                Map中的键值对其实就是元组,只不过元组的元素个数为2,称之为对偶

 def main(args: Array[String]): Unit = {
    val list: List[Any] = List(1,3.14,"l s")
    // 如果list存放的数据类型不一致,那么里面的类型会被标记为共同的父类
    // 导致每个元素自身的类型丢失
    val unit: Any = list(2)
    println(unit)
    // 如果需要对string进行操作  需要自己完成类型转换
    if(unit.isInstanceOf[String]){
      val str: String = unit.asInstanceOf[String]
      val strings: Array[String] = str.split(" ")
      println(strings.toList)
    }
    // 引入元组来保存不同类型的数据,能够记录下每个位置元素的类型
    val tuple: (String, Int) = new Tuple2[String,Int]("hi",1)
    val key: String = tuple._1
    val value: Int = tuple._2

    // tuple在创建的时候,直接使用()来表示
    val tuple01: (String, Int) = ("hi",1)
    //创建map时 可以用二元组来表示
    val map: Map[String, Int] = Map(("hi",1),("nihao",2))
    for (elem <- map) {
      val key01: String = elem._1
      val value01: Int = elem._2
    }
    //map与list转换
    val list1: List[(String, Int)] = map.toList
    println(list1)
  //打印
  list1.foreach((tuple:(String,Int)) =>println(tuple._1 + "\t" + tuple._2))
  }

七、队列

        Scala也提供了队列(Queue)的数据结构,队列的特点就是先进先出。进队和出队的方法分别为enqueue和dequeue。

  def main(args: Array[String]): Unit = {
    val queue: Queue[Int] = Queue(1,2,3,4)

    // 不可变队列即使调用进队的方法  也没有办法将数据加入到队列中 必须创建新对象
    val queue1: Queue[Int] = queue.enqueue(5)
    println(queue)
    println(queue1)

    // 返回值需要保留两个数据  所以设计成了二元组
    // (数据,弹出之后剩下的队列)
    val dequeue: (Int, Queue[Int]) = queue.dequeue
    println(dequeue) //(1,Queue(2, 3, 4))

    val queue2: mutable.Queue[Int] = new mutable.Queue[Int]()
    queue2.enqueue(1,2,3)
    println(queue2)
    val i: Int = queue2.dequeue()
    println(i) //1
    println(queue2) //Queue(2, 3)
  }

八、并行集合

        Scala为了充分使用多核CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。

  def main(args: Array[String]): Unit = {
    // 单线程运行
    // 常规写的代码都是单线程的  在main线程中  有序
   val inclusive: Range.Inclusive = 1 to 100
    //inclusive.foreach((i:Int ) => println(i+ Thread.currentThread().getName))

    // 使用并行集合
    // 会开启多个线程完成任务  造成乱序  只在单个线程中是有序的
    inclusive.par.foreach((i:Int ) => println(i+Thread.currentThread().getName))
  }

上一篇:【题解】CF1530G What a Reversal


下一篇:pygame_鼠标事件