Scala之集合的操作

1) Scala 同时支持不可变集合和可变集合,不可变集合可以安全的并发访问
两个主要的包:
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable
2) Scala 默认采用不可变集合,对于几乎所有的集合类,Scala 都同时提供了可变(mutable)和不可
变(immutable)的版本
3) Scala 的集合有三大类:序列 Seq(有序的,Linear Seq)、集 Set、映射 Map【key->value】,所有的
集合都扩展自 Iterable 特质,在 Scala 中集合有可变(mutable)和不可变(immutable)两种类型。

4) 不可变集合:scala 不可变集合,就是这个 集合本身不能动态变化。(类似 java 的数组,是不可
以动态增长的)
5) 可变集合:可变集合,就是这个 集合本身可以动态变化的。(比如:ArrayList , 是可以动态增长的)

 

不可变数组使用方式

def main(args: Array[String]): Unit = {
    //声明数组第一种方式
    //说明
    //1. 创建了一个 Array 对象,
    //2. [Int] 表示泛型,即该数组中,只能存放 Int
    //3. [Any] 表示 该数组可以存放任意类型
    //4. 在没有赋值情况下,各个元素的值 0
    //5. arr01(3) = 10 表示修改 第 4 个元素的值
    val arr01 = new Array[Int](4) //底层 int[] arr01 = new int[4]
    println(arr01.length) // 4
    println("arr01(0)=" + arr01(0)) // 0
    //数据的遍历
    for (i <- arr01) {
      println(i)
    }
    println("--------------------")
    arr01(3) = 10 //
    for (i <- arr01) {
      println(i)
    }

    //声明数组第二种方式
    //说明
    //1. 使用的是 object Array 的 apply
    //2. 直接初始化数组,这时因为你给了 整数和 "", 这个数组的泛型就 Any
    //3. 遍历方式一样
    var arr02 =Array(1, 3, "xx")
    arr02(1) = "xx"
    for (i <- arr02) {
      println(i)
    }
    //可以使用我们传统的方式遍历,使用下标的方式遍历
    for (index <- 0 until arr02.length) {
      printf("arr02[%d]=%s", index , arr02(index) + "\t")
    }
  }

 可变数组使用方式

def main(args: Array[String]): Unit = {
    import scala.collection.mutable.ArrayBuffer
    //创建 ArrayBuffer
    val arr01 =ArrayBuffer[Any](3, 2, 5)
    //访问,查询
    //通过下标访问元素
    println("arr01(1)=" + arr01(1)) // arr01(1) = 2
    //遍历
    for (i <- arr01) {
      println(i)
    }
    println(arr01.length) //3
    println("arr01.hash=" + arr01.hashCode())

      //修改 [修改值,动态增加]
      //使用 append 追加数据 ,append 支持可变参数
      //可以理解成 java 的数组的扩容
      arr01.append(90.0,13) // (3,2,5,90.0,13)
    println("arr01.hash=" + arr01.hashCode())
    println("===================")
    arr01(1) = 89 //修改 (3,89,5,90.0,13)
    println("--------------------------")
    for (i <- arr01) {
      println(i)
    }
    //删除...
    //删除,是根据下标来说
    arr01.remove(0) // (89,5,90.0,13)
    println("--------删除后的元素遍历---------------")
    for (i <- arr01) {
      println(i)
    }
    println("最新的长度=" + arr01.length) // 4
  }

变长数组分析小结
1) ArrayBuffer 是变长数组,类似 java 的 ArrayList
2) val arr2 =ArrayBuffer[Int]() 也是使用的 apply 方法构建对象
3) def append(elems: A*) { appendAll(elems) } 接收的是可变参数.
4) 每 append 一次,arr 在底层会重新分配空间,进行扩容,arr2 的内存地址会发生变化,也就成
为新的 ArrayBuffer

 

定长数组与变长数组的转换
说明
在开发中,我们可能使用对定长数组和变长数组,进行转换
arr1.toBuffer //定长数组转可变数组
arr2.toArray //可变数组转定长数组
注意事项:
arr2.toArray 返回结果才是一个定长数组, arr2 本身没有变化
arr1.toBuffer 返回结果才是一个可变数组, arr1 本身没有变化

def main(args: Array[String]): Unit = {
    import scala.collection.mutable.ArrayBuffer
    val arr2 =ArrayBuffer[Int]()
    // 追加值
    arr2.append(1, 2, 3)
    println(arr2)
    //说明
    //1. arr2.toArray 调用 arr2 的方法 toArray
    //2. 将 ArrayBuffer ---> Array
    //3. arr2 本身没有任何变化
    val newArr = arr2.toArray
    println(newArr)
    //说明
    //1. newArr.toBuffer 是把 Array->ArrayBuffer
    //2. 底层的实现
    /*
    override def toBuffer[A1 >:A]: mutable.Buffer[A1] = {
    val result = new mutable.ArrayBuffer[A1](size)
    copyToBuffer(result)
    result
    }
    */
    //3. newArr 本身没变化
    val newArr2 = newArr.toBuffer
    newArr2.append(123)
      println(newArr2)
    // //案例演示+说明
  }

多维数组的定义和使用

def main(args: Array[String]): Unit = {
    //创建
    val arr =Array.ofDim[Int](3, 4)
    //遍历
    for (item <- arr) { //取出二维数组的各个元素(一维数组)
      for (item2 <- item) { // 元素(一维数组) 遍历
        print(item2 + "\t")
      }
      println()
    }
    //指定取出
    println(arr(1)(1)) // 0
    //修改值
    arr(1)(1) = 100
    //遍历
    println("=====================")
    for (item <- arr) { //取出二维数组的各个元素(一维数组)
      for (item2 <- item) { // 元素(一维数组) 遍历
        print(item2 + "\t")
      }
      println()
    }
    //使用传统的下标的方式来进行遍历
    println("===================")
    for (i <- 0 to arr.length - 1) { //先对
      for (j <- 0 to arr(i).length - 1) {
        printf("arr[%d][%d]=%d\t", i, j, arr(i)(j))
      }
      println()
    }
  }

 数组-Scala 数组与 Java 的 List 的互转

def main(args: Array[String]): Unit = {
    import scala.collection.mutable.ArrayBuffer
    // Scala 集合和 Java 集合互相转换
    val arr = ArrayBuffer("1", "2", "3")
    /*
    implicit def bufferAsJavaList[A](b : scala.collection.mutable.Buffer[A]) : java.util.List[A] = { /*
    compiled code */ }
    */
    import scala.collection.JavaConversions.bufferAsJavaList
    //对象 ProcessBuilder , 因为 这里使用到上面的 bufferAsJavaList
    val javaArr = new ProcessBuilder(arr) //为什么可以这样使用?
    // 这里 arrList 就是 java 中的 List
    val arrList = javaArr.command()
    println(arrList) //输出 [1, 2, 3]


    //java 的 List 转成 scala 的 ArrayBuffer
    //说明
    //1. asScalaBuffer 是一个隐式函数
    /*
    implicit def asScalaBuffer[A](l : java.util.List[A]) : scala.collection.mutable.Buffer[A] = { /* compiled
    code */ }
    */
    import scala.collection.JavaConversions.asScalaBuffer
    import scala.collection.mutable
    // java.util.List ==> Buffer
    val scalaArr: mutable.Buffer[String] = arrList
    scalaArr.append("jack")
    scalaArr.append("tom")
    scalaArr.remove(0)
    println(scalaArr) // (2,3,jack,tom)
  }

元组 Tuple-元组的基本使用

基本介绍
元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。
说的简单点,就是将多个无关的数据封装为一个整体,称为元组, 最多的特点灵活,对数据没有过
多的约束。
注意:元组中最大只能有 22 个元素

访问元组中的数据,可以采用顺序号(_顺序号),也可以通过索引(productElement)访问。

def main(args: Array[String]): Unit = {
    println("==================访问元组=========================")
    //访问元组
    val t1 = (1, "a", "b", true, 2)
    println(t1._1) // 1 //访问元组的第一个元素 ,从 1 开始
    /*
    override def productElement(n: Int) = n match {
    case 0 => _1
    case 1 => _2
    case 2 => _3
    case 3 => _4
    case 4 => _5
    case _ => throw new IndexOutOfBoundsException(n.toString())
    }
    */
    println(t1.productElement(0)) // 0 // 访问元组的第一个元素,从 0 开始

    println("==================遍历元组=========================")
    //遍历元组, 元组的遍历需要使用到迭代器
    for (item <- t1.productIterator) {
      println("item=" + item)
    }
  }

列表 List的使用,不可变的

Scala 中的 List 和 Java List 不一样,在 Java 中 List 是一个接口,真正存放数据是 ArrayList,而 Scala
的 List 可以直接存放数据,就是一个 object,默认情况下 Scala 的 List 是不可变的,List 属于序列 Seq。
val List = scala.collection.immutable.List
object List extends SeqFactory[List]

1) List 默认为不可变的集合
2) List 在 scala 包对象声明的,因此不需要引入其它包也可以使用
val List = scala.collection.immutable.List
3) List 中可以放任何数据类型,比如 arr1 的类型为 List[Any]
4) 如果希望得到一个空列表,可以使用 Nil 对象, 在 scala 包对象声明的,因此不需要引入其它包也
可以使用
val Nil = scala.collection.immutable.Nil

def main(args: Array[String]): Unit = {
    //说明
    //1. 在默认情况下 List 是 scala.collection.immutable.List,即不可变
    //2. 在 scala 中,List 就是不可变的,如需要使用可变的 List,则使用 ListBuffer
    //3. List 在 package object scala 做了 val List = scala.collection.immutable.List
    //4. val Nil = scala.collection.immutable.Nil // List()
    val list01 = List(1, 2, 3) //创建时,直接分配元素
    println(list01)
    val list02 = Nil //空集合
    println(list02)

    //访问 List 的元素
    val value1 = list01(1) // 1 是索引,表示取出第 2 个元素.
    println("value1=" + value1) // 2

    println("-------------list 追加元素后的效果-----------------")
    //通过 :+ 和 +: 给 list 追加元素(本身的集合并没有变化)
    var list1 = List(1, 2, 3, "abc")
    // :+运算符表示在列表的最后增加数据
    val list2 = list1 :+ 4 // (1,2,3,"abc", 4)
    println(list1) //list1 没有变化 (1, 2, 3, "abc"),说明 list1 还是不可变
    println(list2) //新的列表结果是 [1, 2, 3, "abc", 4]
    val list3 = 10 +: list1 // (10,1, 2, 3, "abc")
    println("list3=" + list3)

    /*
    1) 符号::表示向集合中 新建集合添加元素。
    2) 运算时, 集合对象一定要放置在最右边,
    3) 运算规则,从右向左。
    4) :::  运算符是将集合中的每一个元素加入到集合中去
     */
    //:: 符号的使用
    val list4 = List(1, 2, 3, "abc")
    //说明 val list5 = 4 :: 5 :: 6 :: list4 :: Nil 步骤
    //1. List()
    //2. List(List(1, 2, 3, "abc"))
    //3. List(6,List(1, 2, 3, "abc"))
    //4. List(5,6,List(1, 2, 3, "abc"))
    //5. List(4,5,6,List(1, 2, 3, "abc"))
    val list5 = 4 :: 5 :: 6 :: list4 :: Nil
    println("list5=" + list5)
    //说明 val list6 = 4 :: 5 :: 6 :: list4 ::: Nil 步骤
    //1. List()
    //2. List(1, 2, 3, "abc")
    //3. List(6,1, 2, 3, "abc")
    //4. List(5,6,1, 2, 3, "abc")
    //5. List(4,5,6,1, 2, 3, "abc")
    val list6 = 4 :: 5 :: 6 :: list4 ::: Nil
    println("list6=" + list6)
  }

ListBuffer的基本使用,可变的

def main(args: Array[String]): Unit = {
    import scala.collection.mutable.ListBuffer
    //创建 ListBuffer
    val lst0 = ListBuffer[Int](1, 2, 3)

    //如何访问
    println("lst0(2)=" + lst0(2)) // 输出 lst0(2)= 3
    for (item <- lst0) { // 遍历,是有序
      println("item=" + item)
    }
    // 动态的增加元素,lst1  就会变化,  增加一个一个的元素
    val lst1 = new ListBuffer[Int] // 空的 ListBuffer
    lst1 += 4 // lst1 (4)
    lst1.append(5) // list1(4,5)
    //
    lst0 ++= lst1 // lst0 (1, 2, 3,4,5)
    println("lst0=" + lst0)
    val lst2 = lst0 ++ lst1 // lst2(1, 2, 3,4,5,4,5)
    println("lst2=" + lst2)
    val lst3 = lst0 :+ 5 // lst0 不变 lst3(1, 2, 3,4,5,5)
    println("lst3=" + lst3)
    println("=====删除=======")
    println("lst1=" + lst1)

    lst1.remove(1) //  表示将下标为 1  的元素删除
    for (item <- lst1) {
      println("item=" + item) //4
    }
  }

队列 Queue的使用

1) 队列是一个 有序列表,在底层可以用 数组或是 链表来实现。
2) 其输入和输出要遵循 先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取
3) 在 Scala 中,由设计者直接给我们提供队列类型 Queue 使用。
4) 在 scala 中, 有 scala.collection.mutable.Queue 和 scala.collection.immutable.Queue , 一般来说,我们在开发中通常使用可变集合中的队列。

def main(args: Array[String]): Unit = {
    import scala.collection.mutable
    //创建队列
    val q1 = new mutable.Queue[Int]
    println(q1)

    //给队列增加元素
    q1 += 9 // (9)
    println("q1=" + q1) // (9)
    q1 ++= List(4, 5, 7) // 默认值直接加在队列后面
    println("q1=" + q1) //(9,4,5,7)
    //q1 += List(10,0) // 表示将 List(10,0) 作为一个元素加入到队列中,

    //dequeue 从队列的头部取出元素 q1 本身会变
    val queueElement = q1.dequeue()
    println("queueElement=" + queueElement + "q1=" + q1)
    //enQueue 入队列,默认是从队列的尾部加入. Redis
    q1.enqueue(100, 10, 100, 888)
    println("q1=" + q1) // Queue(4, 5, 7, 100,10,100,888)

    println("============Queue-返回队列的元素=================")
    //队列 Queue-返回队列的元素
    //1. 获取队列的第一个元素
    println(q1.head) // 4, 对 q1 没有任何影响
    //2. 获取队列的最后一个元素
    println(q1.last) // 888, 对 q1 没有任何影响
    //3. 取出队尾的数据 ,即:返回除了第一个以外剩余的元素,可以级联使用
    println(q1.tail) // (5, 7, 100,10,100,888)
    println(q1.tail.tail.tail.tail) // (10,100,888)
  }

映射 Map的使用

Scala 中的不可变 Map 是有序,构建 Map 中的元素底层是 Tuple2 类型

def main(args: Array[String]): Unit = {
    import scala.collection.mutable
    //方式 1-构造不可变映射
    //1.默认 Map 是 immutable.Map
    //2.key-value 类型支持 Any
    //3.在 Map 的底层,每对 key-value 是 Tuple2
    //4.从输出的结果看到,输出顺序和声明顺序一致
    val map1 = Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
    println(map1)

    //方式 2-构造可变映射
    //1.从输出的结果看到,可变的 map 输出顺序和声明顺序不一致
    val map2 = mutable.Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
    println(map2)

    //方式 3-创建空的映射
    val map3 = new scala.collection.mutable.HashMap[String, Int]
    println(map3)

    //方式 4-对偶元组
    //说明
    //即创建包含键值对的二元组, 和第一种方式等价,只是形式上不同而已。
    //对偶元组 就是只含有两个数据的元组。
    val map4 = mutable.Map(("Alice" , 10), ("Bob" , 20), ("Kotlin" , "北京"))
    println("map4=" + map4)


    //映射 Map-取值
    //方式 1-使用 map(key)
    //说明:
    //1) 如果 key 存在,则返回对应的值
    //2) 如果 key 不存在,则抛出异常[java.util.NoSuchElementException]
    //3) 在 Java 中,如果 key 不存在则返回 null
    val value1 = map2("Alice")
    println(value1)
    //抛出异常(java.util.NoSuchElementException: key not found:)
    //println(map4("Alice~"))

    //方式 2-使用 contains 方法检查是否存在 key
    // 返回 Boolean
    // 1.如果 key 存在,则返回 true
    // 2.如果 key 不存在,则返回 false
    //使用 containts 先判断在取值,可以防止异常,并加入相应的处理逻辑
    if (map4.contains("Alice")) {
      println("key 存在,值=" + map4("Alice"))
    } else {
      println("key 不存在:)")
    }

    //方式 3-使用 map.get(key).get 取值
    //通过 映射.get(键) 这样的调用返回一个 Option 对象,要么是 Some,要么是 None
    //1) map.get 方法会将数据进行包装
    //2) 如果 map.get(key) key 存在返回 some,如果 key 不存在,则返回 None
    //3) 如 果 map.get(key).get key 存 在 , 返 回 key 对 应 的 值 , 否 则 , 抛 出 异 常
    //java.util.NoSuchElementException: None.get
    //1. 如果 key 存在 map.get(key) 就会返回 Some(值) ,然后 Some(值).get 就可以取出
    //2. 如果 key 不存在 map.get(key) 就会返回 None
    println(map4.get("Alice").get)
    //println(map4.get("Alice~").get) // 抛出异常

    //方式 4-使用 map4.getOrElse()取值
    // getOrElse 方法 : def getOrElse[V1 >: V](key: K, default: => V1)
    // 说明:
    //1) 如果 key 存在,返回 key 对应的值。
    //2) 如果 key 不存在,返回默认值。也就是"默认的值 鱼 <・)))><<"这句话,第二个参数
    println(map4.getOrElse("Alice~~~","默认的值 鱼 <・)))><<"))

    //如何选择取值的方式,加判断的肯定效率没直接获取效率来的快
    //1) 如果我们确定 map 有这个 key ,则应当使用 map(key), 速度快
    //2) 如果我们不能确定 map 是否有 key ,而且有不同的业务逻辑,使用 map.contains() 先判断在加入逻辑
    //3) 如果只是简单的希望得到一个值,使用 map4.getOrElse("ip","127.0.0.1")


    //Map-对 map 修改、添加和删除
    //更新 map 的元素
    //1) map 是可变的,才能修改,否则报错
    //2) 如果 key  存在:则修改对应的值,key  不存在, 等价于添加一个 key-val
    val map5 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) )
    map5("A") = 20 //增加

    map5 += ("D" -> 4)
    map5 += ("B" -> 5)

    //添加多个元素
    map5 += ("E" -> 6,"F" -> 7)
    val map6 = map5 + ("g" -> 9,"z" -> 8)
    println(map6)

    //删除元素
    //1) "A","B" 就是要删除的 key, 可以写多个.
    //2) 如果 key 存在,就删除,如果 key 不存在,也不会报错.
    map5 -= ("A","B","AAA") //直接填key就行了
    println("map5=" + map5)

    //映射 Map-对 map 遍历
    //对 map 的元素(元组 Tuple2 对象 )进行遍历的方式很多,具体如下
    //val map1 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) )
    //for ((k, v) <- map1) println(k + " is mapped to " + v)
    //for (v <- map1.keys) println(v)
    //for (v <- map1.values) println(v)
    //for(v <- map1) println(v) //v 是 Tuple?
    //说明
    //1.每遍历一次,返回的元素是 Tuple2
    //2.取出的时候,可以按照元组的方式来取
    val map7 = mutable.Map(("A", 1), ("B", "北京"), ("C", 3))
    println("----(k, v) <- map6--------")
    for ((k, v) <- map7) println(k + " is mapped to " + v)
    println("----v <- map6.keys--------")
    for (v <- map7.keys) println(v)
    println("----v <- map6.values--------")
    for (v <- map7.values) println(v)
    //这样取出方式 v 类型是 Tuple2
    println("----v <- map7--------")
    for (v <- map7) println(v + " key =" + v._1 + " val=" + v._2) //v 是 Tuple?

  }

集 Set-基本使用

集是 不重复元素的结合。集 不保留顺序,默认是以 哈希集实现

def main(args: Array[String]): Unit = {
    import scala.collection.mutable
    val set = Set(1, 2, 3) //不可变
    println(set)

    val mutableSet = mutable.Set(1,2,"hello") //可以变
    println("mutableSet" + mutableSet)

    //可变集合的元素添加
    //说明:如果添加的对象已经存在,则不会重复添加,也不会报错
    mutableSet.add(4) //方式 1
    mutableSet += 6 //方式 2
    mutableSet.+=(5) //方式 3

    //删除
    //说明:说明:如果删除的对象不存在,则不生效,也不会报错
    val set02 = mutable.Set(1,2,4,"abc")
    set02 -= 2 // 操作符形式
    set02.remove("abc") // 方法的形式,scala 的 Set 可以直接删除值

    //set 集合的遍历操作
    val set03 = mutable.Set(1, 2, 4, "abc")
    for(x <- set03) {
      println(x)
    }
  }

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值