Scala核心编程(10)-集合(上)

集合简介

  • Scala同时支不可变集合变集
  • 个主要的包:

        不可变集合:scala.collection.immutable(类似java中数组)

        可变集合:  scala.collection.mutable (类似java中ArrayList)

  • Scala默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可(mutable)不可(immutable)
  • Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)两种类型。  

 可变集合继承关系一览图

  不可变集合继承关系一览图

数组的定义 

不变长度数组 

    var t: Array[Int] = new Array[Int](4)
    //集合元素采用小括号访问
    t(1) = 13 //赋值操作
    for (i <- Range(0, t.length)) {
      print(i + " -> " + t(i) + ",")
    }
    println()
    var arr: Array[Int] = Array(1, 24, 4)
    //不同的便利方式
    for (element <- arr) {
      print("element -> " + element + ",")
    }

//输出
// 0 -> 0,1 -> 13,2 -> 0,3 -> 0
// element -> 1,element -> 24,element -> 4

可变长度数组

    var buf = ArrayBuffer[Any](3, 2, 4)
    //追加元素
    buf.append(12)
    //追加多个元素
    buf.append(13, "abc", 20)
    //重新赋值(修改)
    buf(0) = 43
    //添加元素后输出
    for (e <- buf) {
      print(e + ",")
    }
    println()
    //删除元素
    buf.remove(1)
    //删除元素后输出
    for (e <- buf) {
      print(e + ",")
    }
    println()

// 输出
//初始化添加元素后: 43,2,4,12,13,abc,20,
//删除指定的元素后: 43,4,12,13,abc,20,

 可变长度数组和不可变长度数组互转

PS:原数据并没有变化,只是返回的新对象和原对象不同

    var array: Array[Int] = new Array[Int](4)
    
    var buf = ArrayBuffer[Any](3, 2, 4)
    
    //可变数组转定长数组 仅仅tArray是定长数组,buf对象没有变化
    var tArray: Array[Any] = buf.toArray

    //定长数组转可变数组 仅仅tBuf是可变数组,t对象么有变
    var tBuf: mutable.Buffer[Int] = array.toBuffer

总结

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

多维数组定义 

案例是定义一个二维数组,有个四个元素(一维数组),每个一维数组有五个元素

    val array1 = Array.ofDim[Int](4, 5)
    array1(1)(1) = 5
    array1(2)(2) = 3
    for (item <- array1) {
      for (item2 <- item) {
        print(item2 + "\t")
      }
      println()
    }
// 输出
// 0	0	0	0	0	
// 0	5	0	0	0	
// 0	0	3	0	0	
// 0	0	0	0	0

scala数组和Java中List互转

import scala.collection.{JavaConverters, mutable}
import scala.collection.mutable.ArrayBuffer

object ConvertDemo {
    def main(args: Array[String]): Unit = {
        var list = JavaConverters.bufferAsJavaListConverter(buf)
        var list1: java.util.List[Any] = list.asJava
        println(list1)
        var buf1 = JavaConverters.asScalaBufferConverter(list1)
        var buf11: mutable.Buffer[Any] = buf1.asScala
        println(buf11)
    }
}

元组(Tuple)

组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。

大致是将多个无关的数据封装为一个整体,其的特点灵活,数据没有过多的约束

Ps:组中最大只能有22个元

object TupleDemo {
  def main(args: Array[String]): Unit = {
    var tup1 = 1 -> "one"
    var tup2 = (1, 2, 3, 4, "five", tup1)
    //->操作 最终都生成一个新的两个元素的
    var tup3 = tup1 -> "元素1" -> "元素2" -> "元素3"
    println("元组1:" + tup1)
    println("元组2:" + tup2)
    println("元组2-第一个元素:" + tup2._1)
    println("元组2-第二个元素:" + tup2._2)
    println("元组2-第三个元素:" + tup2._3)
    println("元组2-第三个元素:" + tup2.productElement(2))
    println("元组3:" + tup3)
    print("元组3-使用迭代器遍历:")
    var it = tup3.productIterator
    it.foreach(x => print(x + ","))
    println()
    print("元组3-反转后使用迭代器遍历:")
    tup3.swap.productIterator.foreach(x => print(x + ","))
}
# -> 该操作符最终生成一个两个元素的元组
# productElement方法底层就是使用了._x 的操作

元组1:(1,one)
元组2:(1,2,3,4,five,(1,one))
元组2-第一个元素:1
元组2-第二个元素:2
元组2-第三个元素:3
元组2-第三个元素:3
元组3:((((1,one),元素1),元素2),元素3)
元组3-使用迭代器遍历:(((1,one),元素1),元素2),元素3
元组3-反转后使用迭代器遍历:元素3,(((1,one),元素1),元素2)

 

列表(List) 

Scala中的List Java List 不一样,JavaList是一个接口,真正存放数据是ArrayList,而ScalaList可以直接存放数据,就是一个object认情况下ScalaList是不可变的List属于序列Seq

 创建列表

var list: List[Int] = List(1, 2, 3)

添加元素

列表中增加元素, 会返回新的/集合对象,原集合没有发生任何变化

PSScalaList元素的追加形式非常独特,和Java不一样

    //定义一个集合
    var list: List[Int] = List(1, 2, 3)
    println("原集合打印: " + list)
    list.iterator.foreach(x => print(x + ","))
    println()
    println("原集合的第一个元素: " + list(0))
    //在集合头部增加一个元素
    println("使用::和+: 列表在头部增加元素")
    var list1 = list.::(5)
    var list2 = list.+:(6)
    println("list1: " + list1)
    println("list2: " + list2)
    //在集合尾部增加元素
    var list3 = list :+ 6
    var list4 = 5 +: list :+ 13
    println("list对象使用:+ , 元素使用+:列表尾部部增加元素")
    println("list3: " + list3)
    println("list4: " + list4)

    println("list4: " + (4 :: 5 :: Nil))

    println("::运算符")
    //:: 元素使用:: 运算符在首部添加元素,列表需要放在最后
    var list5 = 6 :: 5 :: list :: Nil
    var list6 = list.::(5).::(6)
    println("list5: " + list5)
    println("list6: " + list6)

    println(":::运算符")
    var list7 = 4 :: 5 :: 6 :: list ::: list ::: list
    var list8 = list.:::(list).:::(list).::(6).::(5).::(4)
    println("list7: " + list7)
    println("list8: " + list8)

    var o1: List[Int] = List(1, 1)
    var o2: List[Int] = List(2, 2)
    var o3: List[Int] = List(3, 3)
    println("组合看执行顺序: " + (o3 :: list))
    println("组合看执行顺序: " + (o2 ::: o3 :: list))
    println("组合看执行顺序: " + (o1 :: o2 ::: o3 :: list))
    println("组合看执行顺序: " + (list ::: o1 :: o2 ::: o3 :: list))
    println("组合看执行顺序: " + (4 :: list ::: o1 :: o2 ::: o3 :: list))

运行结果 

原集合打印: List(1, 2, 3)
1,2,3,
原集合的第一个元素: 1
使用::和+: 列表在头部增加元素
list1: List(5, 1, 2, 3)
list2: List(6, 1, 2, 3)
list对象使用:+ , 元素使用+:列表尾部部增加元素
list3: List(1, 2, 3, 6)
list4: List(5, 1, 2, 3, 13)
list4: List(4, 5)
::运算符
list5: List(6, 5, List(1, 2, 3))
list6: List(6, 5, 1, 2, 3)
:::运算符
list7: List(4, 5, 6, 1, 2, 3, 1, 2, 3, 1, 2, 3)
list8: List(4, 5, 6, 1, 2, 3, 1, 2, 3, 1, 2, 3)
组合看执行顺序: List(List(3, 3), 1, 2, 3)
组合看执行顺序: List(2, 2, List(3, 3), 1, 2, 3)
组合看执行顺序: List(List(1, 1), 2, 2, List(3, 3), 1, 2, 3)
组合看执行顺序: List(1, 2, 3, List(1, 1), 2, 2, List(3, 3), 1, 2, 3)
组合看执行顺序: List(4, 1, 2, 3, List(1, 1), 2, 2, List(3, 3), 1, 2, 3)

列表总结

运算符 

数据获取

list(0)---- 获取第一个元素

PS:可以使用迭代器,或者是for循环进行遍历 

 :+  和 +:

:+ 表示尾部增加元素

+: 表示头部增加元素

list 使用 :+  在尾部增加数据

元素使用 +:在列表头部增加数据,等同与 list.+:(x) / list.::(x)

 :: 等价为list.::(x)

表示向集合中添加元素,执行数序为从右到左

PS: 集合对象一定要放置到最右边,且至少右边有一个集合对象

 :::等价为list.:::(x)

两个集合间的操作,将集合中的每一个元素加入到另一个集合中去

PS: 执行数序为从右到左,有且至少有个两个集合对象

列表(ListBuffer )

ListBuffer可变list集合,可以添加,删除元素,ListBuffer

    val buffer = ListBuffer[Int](1, 2, 3)
    println("buffer(2)=" + buffer(2))
    print("输出可变集合: ")
    for (item <- buffer) {
      print(item + ", ")
    }
    println()
    val buffer1 = new ListBuffer[Int]
    //添加元素
    buffer1 += 4
    //追加元素
    buffer1.append(7)
    buffer1.append(5, 34, 3, 5)
    //两个集合合并
    val buffer2 = buffer ++ buffer1
    //追加元素
    val buffer3 = buffer :+ 5
    println("buffer=" + buffer)
    println("buffer1=" + buffer1)
    println("buffer2=" + buffer2)
    println("buffer3=" + buffer3)
    //删除元素
    buffer1.remove(1)
    print("删除后输出可变集合: ")
    for (item <- buffer1) {
      print(item + ", ")
    }
// 输出结果
buffer(2)=3
输出可变集合: 1, 2, 3, 
buffer=ListBuffer(1, 2, 3)
buffer1=ListBuffer(4, 7, 5, 34, 3, 5)
buffer2=ListBuffer(1, 2, 3, 4, 7, 5, 34, 3, 5)
buffer3=ListBuffer(1, 2, 3, 5)
删除后输出可变集合: 4, 5, 34, 3, 5, 

队列(Queue

  • 队列是一个有序列表,在底层可以用数组或是链表来实现
  • 其输入和输出要遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
  • Scala中,由设计者直接给我们提供队列类型使用。
  • scala, scala.collection.mutable.Queue scala.collection.immutable.Queue , 般来说,我们在开发中通常使用可变集合中的队列。
    //创建队列对象
    var q1 = new mutable.Queue[Int]
    //增加一个元素
    q1 += 20
    //两个集合连接声明一个新的集合(原集合不变)
    var q2 = q1 ++ List(1, 23)
    //增加一个集合 并重复赋值给当前对象
    q1 ++= List(1, 23)
    println("++=之后: " + q1)
    println("++赋值给其他集合后: " + q2)
    println("第一元素:" + q1.head)
    println("最后元素:" + q1.last)
    //去除第一个之后的队列对象
    println("尾部对象(去除首个元素):" + q1.tail)
    //删除一个元素
    q2.dequeue()
    q2.dequeueAll(x => x > 3)
    println("删除元素之后: " + q2)
    //增加元素
    q2.enqueue(20, 23)
    println("删除并增加元素之后: " + q2)
// 输出
++=之后: Queue(20, 1, 23)
++赋值给其他集合后: Queue(20, 1, 23)
第一元素:20
最后元素:23
尾部对象(去除首个元素):Queue(1, 23)
删除元素之后: Queue(1)
删除并增加元素之后: Queue(1, 20, 23)

映射(Map)

  • Scala中的Map Java类似,也是一个散列表,它存储的内容也是键值对(key-value)射,Scala不可变的Map是有序的,可变的Map是无序的。
  • Scala中,有可变Map (scala.collection.mutable.Map) 和 不可变Map(scala.collection.immutable.Map)

创建map方式 

1.直接创建 

注意点:

  1. 集合中的元素实际就是Tuple2类型;
  2. 不可变map是有序的;
  3. 可变map是无序的;
  4. 默认没有引包的情况下Map是不可变Map
    //创建map的方式
    //1. 直接声明可变或者是不可变map
    val map1 = scala.collection.mutable.Map("AAA" -> 1, "BBB" -> 2, "CCC" -> 3) //可变
    //总结:不可变map是有序的;集合中的元素实际就是Tuple2类型;默认没有引包的情况下Map是不可变Map
    val map2 = scala.collection.immutable.Map("AAA" -> 1, "BBB" -> 2, "CCC" -> 3) //不可变

2.使用new关键字创建

PS:对于可变map能做一些业务逻辑,如果创建一个空的不可变map用处不大

    //2.使用new关键字创建空的map
    val map3 = new mutable.HashMap[String, Int]() //可变
    val map4 = new HashMap[String, String]() //不可变

 3.对偶元组(和第一种创建方式等价)

   val map5 = mutable.Map(("AAA", "aaa"), ("BBB", "bbb")) //可变
   val map6 = Map(("AAA", "aaa"), ("BBB", "bbb")) // 不可变(默认使用的是不可变的map)

Map元素操作 

PS:

  • 元素新增、修改、删除真对于可变map
  • 添加元素时,如果当前key不存在就新增,如果已经存在就修改
  • 删除元素时,如果key不存在不会报错
    // 只有可变的map才能修改、增加、删除元素
    // 添加元素,如果key已经存在就修改,如果不存在就添加
    map3("AAA") = 1
    map3 += ("AAA" -> 44) //添加一个元素(如果已经存在该key相当于修改)
    map3 += ("BBB" -> 11, "CCC" -> 22) //添加多个元素
    println("添加元素之后的map: " + map3)
    map3 -= ("FFF") //key如果存在就直接删除,如果不存在也不会报错
    map3 -= ("DDD", "CCC") // 可以支持删除多个key

map元素的获取 

  1. map("key")                                 :没有对应的key会报错
  2. map.get("key").get                     :没有对应的key会获取到None,会报错
  3. map.getOrElse("key","默认值")  :没有对应的key会返回默认值

PS: 因为不存在key会报错,可以使用map.contains("key")判断存在再获取

    //获取元素的方式
    println("map获取值")
    // 如果没有对应的key会报错
    println("map获取值-1: map3(\"AAA\")= " + map3("AAA"))
    // 如果没有对应的key会产生None,然后会报.NoSuchElementException
    println("map获取值-2: map3.get(\"AAA\").get= " + map3.get("AAA").get)
    //如果对应的key能取到值就返回该值,否则就返回对应的默认值
    println("map获取值-3:map3.getOrElse(\"AAAC\", -1)= " + map3.getOrElse("AAAC", -1))

    println("包含key判断:map3.contains(\"AAA\")= " + map3.contains("AAA"))

 map遍历

    // 遍历map对象
    println("遍历map")
    println("遍历map-1: 使用key,value遍历map")
    for ((k, v) <- map3) print(k + " = " + v + ", ")
    println()
    println("遍历map-2: 遍历map的key")
    for (k <- map3.keys) print(k + ", ")
    println()
    println("遍历map-3: 遍历map的value")
    for (k <- map3.values) print(k + ", ")
    println()
    println("遍历map-4: 遍历map的中的对象")
    for (k <- map3) print(k + ", ")
    println()
    println("遍历map-5: 使用foreach遍历")
    map3.foreach(e => print(e._1 + " - " + e._2 + ", "))

集合(Set)

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

默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set

 集合创建

    //不可变集合
    val set1 = Set(1, 2, 3)
    //可变集合
    val set2 = scala.collection.mutable.Set(4, 5, 6, "")
    //可变空集合
    val set3 = new mutable.HashSet[Int]()

 集合操作

 //添加操作,如果元素已经存在不做任何处理,也不报错
    set3.add(11)
    set3 += 22
    set3.+=(33)
    //删除操作
    set3 -= 22
    set3.-=(22)
    set3.remove(44)
    set3.foreach(x => print(x))
    //直接操作+ - 会产生新集合,原集合不变
    val set4 = set3 + 5
    val set5 = set3 - 33
    set3 += 113
    //集合1连接集合2(原集合不变)
    val set6 = set3 ++ set4
    //集合1减去集合2(原集合不变)
    val set7 = set3 -- set4
    println()
    println("set3: " + set3)
    println("set3max: " + set3.max)
    println("set3min: " + set3.min)
    println("set4: " + set4)
    println("set5: " + set5)
    println("set6: " + set6)
    println("set7: " + set7)

 集合遍历

    println("遍历集合: ")
    for (x <- set3) {
      print(x + ", ")
    }
    println()
    set3.foreach(x => print(x + ", "))

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值