12_Scala_数据结构上_Array_Tuple_List_Queue_Map_Set

举报
alexsully 发表于 2021/05/07 20:13:11 2021/05/07
【摘要】 1 immutable & mutable 2 array tuple list queue map set

Scala 集合都扩展自Iterable特质
三大类:序列Seq 集Set  映射Map 都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)两种类型

scala.collection.immutable (不可变) 1 可以安全的并发访问  2 不懂动态扩展 类似Java数组
scala.collection.mutable (可变) 1 本身可变,类似arrayList 动态扩展





1 数组  构建 
   new Array[泛型](长度) 中括号泛型,小括号访问  arr(1)
   apply方法创建数组对象 val arr1 = Array(1, 2)

object ArrayDemo01 {
  def main(args: Array[String]): Unit = {
     // 方式一 数组等同于Java中的数组,中括号的类型就是数组的类型
     // [Int] 表示泛型,即该数组中,只能存放Int
     // [Any] 表示 该数组可以存放任意类型
    val a1 = new Array[Any](3)  //底层 int[] a1 = new int[4]
    a1(0) =10
    a1(1) ="alex"
    a1(2) = true

    for( i <- a1){
      println(i)
    }
    val a2 = a1.mkString(" ")


    //方式二 直接赋值  object Array 的apply
    //1. 使用的是 object Array 的apply
    //2. 直接初始化数组,因为包括了int和 "", 数组的泛型就Any
    var aa2 = Array(1, 2, "bob")
    aa2(1) = "alex"
    println(aa2.length)
    //可以使用我们传统的方式遍历,使用下标的方式遍历
    for (index <- 0 until aa2.length) {
      printf("arr02[%d]=%s", index , aa2(index) + "\t")
    }
    println()


    println("*****")

    // 变长数组 必须指定泛型 [类型]  (初始值,可有可无)
    val abuffer = ArrayBuffer[Any](10, 20, 30) // append 内容后,底层是创建了一个新地址 返回给 val

    println(abuffer.length + " " + abuffer.hashCode()) //3  573686093

//    for (index <- 0 until abuffer.length ){
//      println(abuffer(index))
//    }
//    abuffer.append("alex","bob") //追加数据,过时了
//    abuffer.appendAll("alex")
    abuffer.appendAll(Array(50, 60,70))   //appendAll(要求传入一个 iterable实现类)
    println(abuffer.length + " " + abuffer.hashCode())

    abuffer(1) = 200  //修改
    abuffer.remove(0) //删除,是根据下标索引 来删除
    abuffer.remove(0,2) // index  int  count int


    //1. abuffer.toArray 调用 abuffer的方法 toArray 将 ArrayBuffer ---> Array
    //2. arr2本身没有任何变化
    val array = abuffer.toArray

    // Array --->  ArrayBuffer  array 本身没有变化 返回一个新的 ArrayBuffer
    val abuffer_new = array.toBuffer


    // 多维数组
    val arrDim = Array.ofDim[Int](2, 5)
    arrDim(1)(1) =10
    // 遍历1
    //0	0	0	0	0
    //0	10	0	0	0
    for (i <- arrDim){
      for (j <- i){
        println(j + "\t")
      }
      println()
    }

    // 遍历2
    for (i <- 0 to arrDim.length -1  ){
      for (j <- 0 to arrDim(i).length -1){
        printf("arr[%d][%d]=%d\t", i, j, arrDim(i)(j))
      }
      println()
    }
  }}


2 Tuple-元组 最大只能有22个元素 可以存放各种相同或不同类型的数据元祖类型取决于后面放多少个元素)

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

object TupleTest {
  def main(args: Array[String]): Unit = {
//灵活
    var tup1 = (10, 20, 30, "hello", 40) //10 访问元祖第一个元素  从1开始
    println(tup1) //(10,20,30,hello,40)
 // 1从1开始  访问元组的第一个元素
    println(tup1._1)  //10 访问元祖第一个元素, 从0开始
    println(tup1._3)  //30

/*
override def productElement(n : scala.Int) : scala.Any = { /* compiled code */ }
  def _1 : T1
  def _2 : T2
  def _3 : T3
 */
 // 0从0开始  访问元组的第一个元素
    println(tup1.productElement(0))  //10
    println(tup1.productElement(2))  //30

    //遍历 需要迭代器

    for (i <- tup1.productIterator) { //用迭代器实现的,移动的指针
      println(i)
    } }
}


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

object ListTest1 {
  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(10,20,"alex")
    val list02  = Nil  //List()
    println(list01 + "  " + list02)
  
    // 追加元素
    // :+ 表示在列表的最后增加数据
    val list04 = list01:+ 40
    // +: 表示在列表的开头增加数据
    val list05 = 50 +: list04
    println(list04 + "  " + list05)   //List(10, 20, alex, 40)  List(50, 10, 20, alex, 40)

    //:: 运算符的使用 --> 逐步添加

    val list_a = List(1,2,3)
    val list_b = 4::5::6:: list_a
    println(list_b) //List(4, 5, 6, 1, 2, 3)
    val list_b2 =4::5::6:: list_a :: Nil   //List(4, 5, 6, List(1,2,3))  List(1,2,3) 是个整体

    val List_c = List(10,20,30)
    val list_d = 50::40::List_c:::Nil

    // ::: 拆开后加入List 里面 (集合每个元素添加到新集合)
    println(list_d) //List(50, 40, 10, 20, 30)
  }
}


object ListBufferTest {

  def main(args: Array[String]): Unit = {
    //创建ListBuffer apply
    val lst0 = ListBuffer[Int](10,20,30)
    
    //动态的增加元素,lst1就会变化, 增加一个一个的元素
    val lst1 = new ListBuffer[Int] //空的ListBuffer

    // 两种添加方式  1 运算符 +=   2 方法  append
    lst1 += 40// lst1 (40)
    lst1.append(50)// list1(40,50)

    //一个集合加到另个集合   list1是被加的,list0有变化
    lst0 ++= lst1 // lst0 (10, 20, 30, 40, 50)

    println("lst0=" + lst0) //ListBuffer(10, 20, 30, 40, 50)
    
    val lst2 = lst0 ++ lst1 //返回新的ListBuffer(10, 20, 30, 40, 50, 40, 50) lst0 不变
    println("lst2=" + lst2)

    val lst3 = lst0 :+ 60   // lst0不变 返回新的 ListBuffer(10, 20, 30, 40, 50, 60)
    println("lst3=" + lst3)

    println("=====删除=======")
    println("lst1=" + lst1)
    lst1.remove(1) // 表示将下标为1的元素删除 , 角标从0开始
    for (item <- lst1) { // list1(40,50)
      println("item=" + item) //40
    }}}


4 Queue
有序列表,在底层可以用数组或是链表来实现。
先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
scala.collection.mutable.Queue (常用) scala.collection.immutable.Queue

object QueueTest {
  def main(args: Array[String]): Unit = {
    // 创建  [泛型]
    val queue1 = new mutable.Queue[Any]()
    // 添加元素方式
    //1 运算符方式  +  添加单个元素
    queue1 += 20
    //2 ++= List() 默认值list里的元素加入到 queue的最后面
    queue1 ++= List(30,40)
    println(queue1)  //Queue(20, 30, 40)

    //3  += List()  作为一个整体加入队列  要求queue类型是any
    queue1 += List(10,0)
    println(queue1) //Queue(20, 30, 40, List(10, 0))

    // 出队列, 默认从队首取数据 取出元素(弹出去) 自身变化,
    val qvalue = queue1.dequeue()
    println(qvalue + " queue1: " + queue1) //20 queue1: Queue(30, 40, List(10, 0))
    // 入队列 默认加入队尾  自身变化
    queue1.enqueue(100,200)
    println( " queue1: " + queue1)  // queue1: Queue(30, 40, List(10, 0), 100, 200)

    //队列 Queue-返回队列的元素  查询类
    //1. 获取队列的第一个元素
    println(queue1.head) // 对q1没有任何影响  30
    //2. 获取队列的最后一个元素
    println(queue1.last) //  对q1没有任何影响 200
    //3. 取出队尾的数据 ,即:返回除了第一个以外剩余的元素,可以级联使用
    println(queue1.tail) // Queue(40, List(10, 0), 100, 200)
    println(queue1.tail.tail.tail.tail) // Queue(200)
  }
}

5 Map

HashMap 是一个散列表(数组+链表),它存储的内容是键值对(key-value)映射,Java中的HashMap是无序的,key不能重复
Scala中的Map 散列表(key 唯一后才能散列) 存键值对(key-value)映射
scala.collection.mutable.Map  和  scala.collection.immutable.Map  是有序的 

object MapTest {
  def main(args: Array[String]): Unit = {

    //方式1-构造不可变映射
    //1.默认Map是 immutable.Map 无法操作 增加/删除
    //2.key-value 类型支持Any .在Map的底层,每对key-value是Tuple2
    //3.从输出的结果看到,输出顺序和声明顺序一致

    val map1 = Map("Alex" -> 30, "BoB" -> 40, "Robbin" -> 28)
    println(map1) //Map(Alex -> 30, BoB -> 40, Robbin -> 28)

    //方式2-构造可变映射
    //1. 可变的map输出顺序和声明顺序不一致
    //2. 支持动态变化
//    val map2 = mutable.Map("Alex" -> 30, "BoB" -> 40, "Robbin" -> 28)
//    println(map2) //HashMap(Alex -> 30, BoB -> 40, Robbin -> 28)

    //方式3-创建空的映射 泛型可以是[any, any ]
//    val map3 = new mutable.HashMap[Any, Any]()
//    println(map3) //HashMap()

    //方式4-对偶元组  也可以混用 方式1 方式四  because 底层就是tuple2
    val map4 = mutable.Map(("Alex", 35), ("BoB", 45))
    println(map4) //HashMap(Alex -> 35, BoB -> 45)

    println("************************")

    //查询取数据
    //方式1-使用map(key) 如果输入key不存在 会抛出异常(java.util.NoSuchElementException: key not found:)
//    println(map4("Alice"))


    //方式2-使用contains方法检查是否存在key
    if (map4.contains("Alex")) {
      println("key存在,值=" + map4("Alex"))
    } else {println("key不存在:)")}

    //方式3 方式3-使用map.get(key).get取值
    //1. 如果key存在 map.get(key) 就会返回Some(值)  ,然后Some(值).get就可以取出
    //2. 如果key不存在 map.get(key) 就会返回None

//    println(map4.get("Alice").get) // 抛出异常 NoSuchElementException: None.get


    //方式4-使用map4.getOrElse()取值
//    println(map4.getOrElse("Alex~~", "默认的值Alexander"))

    println("************************")

   // 修改操作
    val map5 = mutable.Map(("A", 1), ("B", "北京"), ("C", 3))
    // 修改  增加 & 修改
    map5("A") = 20 // A -> 20

    //  修改 += 增加 & 修改
    map5 += ("A" -> 100)
    println("map5=" + map5)  //map5=HashMap(A -> 100, B -> 北京, C -> 3)

    //  修改 -= 去除 & 修改
    map5 -= ("A", "B", "AAA") // 去除 Key 为 A B AAA的
    println("map5=" + map5)

    println("************************")

    // 遍历操作
    // 输出 K V
    for ((k,v) <- map1) println(k + " map to " + v)

    // 单独输出 Key  Values
    for (k <- map1.keys ) println(k)
    for (v <- map1.values) println(v)

    // 用tuple2 形式输出 Key & Value
    for (tupleValues <- map1) println("key: " +tupleValues._1 + " values: "+  tupleValues._2 )
  }
}

6 集合 (不重复 无顺序)  默认是以哈希集实现
java,HashSet是实现Set<E>接口的一个实体类,数据是以哈希表的形式存放的,存不重复 无序的数据 
Scala  使用的是不可变集合,如想使用可变集合,需要引用 scala.collection.mutable.Set 包

object SetTest {
  def main(args: Array[String]): Unit = {
    // 默认不可变
    val set_immut = Set(1, 2, 3)
    println(set_immut)

    // 可变的 导包 import scala.collection.mutable
    val set_mutable = mutable.Set(10, 20, 30)  

    // 添加操作
    set_mutable.add(40)  // 方法
    set_mutable+=50      // 操作符添加
    set_mutable+=(60)

    println(set_mutable) //HashSet(50, 20, 40, 10, 60, 30)

    // 去除操作
    set_mutable -= 10  //操作符形式
    set_mutable -= 20
    set_mutable.remove( 30) // 调用方法形式  返回值是布尔值

    println(set_mutable)   //HashSet(50, 40, 60)
    
    // 遍历
    for (i <- set_mutable) println(i )
  }
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。