10. Scala數據結構(上)-集合操作

来源:https://www.cnblogs.com/zhanghuicheng/archive/2019/05/09/10817519.html
-Advertisement-
Play Games

10.1 數據結構特點 10.1.1 Scala集合基本介紹 uml => 統一建模語言 1) Scala同時支持不可變集合和可變集合,不可變集合可以安全的併發訪問 兩個主要的包 不可變集合:scala.collection.immutable 可變集合:scala.collection.mutab ...


10.1 數據結構特點 

  10.1.1 Scala集合基本介紹 

      uml => 統一建模語言

      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)

  10.1.2 可變集合和不可變集合舉例 

      1) 不可變集合:Scala不可變集合,就是集合本身不能動態變化(類似Java的數組,是不可以動態增長的)

      2) 可變集合:可變集合,就是這個集合本身可以動態變化(比如:ArrayList,是可以動態增長的)

      3) 使用Java做了一個簡單的案例

import java.util.ArrayList;

public class JavaCollection {
    public static void main(String[] args) {
        //不可變集合類似java的數組
        int[] nums = new int[3];
        nums[2] = 6; //?
        nums[2] = 7;
        //nums[3] = 8; //?

//        String[] names = {"bj", "sh"};
//        System.out.println(nums + " " + names);
//
//        //可變集合舉例
        ArrayList al = new ArrayList<String>();
        al.add("狗蛋");
        al.add("鐵蛋");
        System.out.println(al + " 地址= " + al.hashCode()); //地址
        al.add("熊大");
        System.out.println(al + " 地址2=" + al.hashCode()); //地址

    }
}

10.2 不可變集合繼承層次一覽圖

  10.2.1 圖

  10.2.2 小結

      1) Set、Map是Java中也有的集合

      2) Seq是Java沒有的,我們發現List歸屬到Seq了,因此這裡的List就和Java不是同一個概念了

      3) 前面講述的for迴圈有一個1 to 3,就是IndexedSeq下的Vector

      4) String也是屬於IndexedSeq

      5) 經典的數據結構比如Queue和Stack被歸屬到LinearSeq

      6) 註意Scala中的Map體系中有一個SortedMap,說明Scala的Map可以支持排序

      7) IndexSeq和LinearSeq的區別[IndexSeq是通過索引來查找和定位,因此速度快,比如String就是一個索引集合,通過索引即可定位] [LinearSeq是線型的,即有頭尾的概念,這種數據結構一般是通過遍歷來查找,它的價值在於應用到一些具體的應用場景(電商網站,大數據推薦系統:最近瀏覽的10個商品)]

10.3 可變集合繼承層次一覽圖

  10.3.1 圖

  10.3.2 對上圖的說明 

      1) 在可變集合中比不可變集合更豐富

      2) 在Seq集合中,增加了Buffer集合,常用的有ArrayBuffer和ListBuffer

      3) 如果涉及到線程安全問題可以選擇使用syn...開頭的集合

10.4 數組-定長數組(聲明泛型) 

  10.4.1 第一種方式定義數組

      -說明

        這裡的數組等同於Java中的數組,中括弧的類型就是數組的類型

        val arr = new Array[Int](10)

        arr(1) = 9

      -案例演示

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    //說明
    //1. 創建了一個Array對象,
    //2. [Int] 表示泛型,即該數組中,只能存放Int
    //3. [Any] 表示 該數組可以存放任意類型
    //4. 在沒有賦值情況下,各個元素的值 0
    //5.  arr(3) = 10 表示修改 第4個元素的值
    val arr = new Array[Int](4) //底層 int[] arr = new int[4]
    println(arr.length) // 4

    println("arr(0)=" + arr(0)) // 0
    //數據的遍歷

    for (i <- arr) {
      println(i)
    }
    println("--------------------")
    arr(3) = 10 //
    for (i <- arr) {
      println(i)
    }

  }
}

  10.4.2 第二種方式定義數組 

      -說明

        在定義數組時,直接賦值

        //使用apply方法創建數組對象

        val arr = Apply(1,2)

      -案例演示

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    //說明
    //1. 使用的是 object Array 的apply
    //2. 直接初始化數組,這時因為你給了 整數和 "", 這個數組的泛型就Any
    //3. 遍歷方式一樣
    var arr = Array(1, 3, "xx")
    arr(1) = "xx"
    for (i <- arr) {
      println(i)
    }

    //可以使用我們傳統的方式遍歷,使用下標的方式遍歷
    for (index <- 0 until arr.length) {
      printf("arr02[%d]=%s", index, arr(index) + "\t")
    }

  }
}

10.5 數組-變長數組[聲明泛型]  

      -說明

        //定義/聲明

        val arr = ArrayBuffer[Int]()

        //追加值/元素

        arr.append(9)

        //重新賦值

        arr(0) = 6

      -案例演示

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    //創建ArrayBuffer
    val arr = ArrayBuffer[Any](3, 2, 5)

    //訪問,查詢
    //通過下標訪問元素
    println("arr(1)=" + arr(1)) // arr(1) = 2
    //遍歷
    for (i <- arr) {
      println(i)
    }
    println(arr.length) //3
    println("arr.hash=" + arr.hashCode())


    //修改 [修改值,動態增加]
    //使用append 追加數據 ,append支持可變參數
    //可以理解成java的數組的擴容
    arr.append(90.0, 13) // (3,2,5,90.0,13)
    println("arr.hash=" + arr.hashCode())


    println("===================")


    arr(1) = 89 //修改 (3,89,5,90.0,13)
    println("--------------------------")
    for (i <- arr) {
      println(i)
    }

    //刪除...
    //刪除,是根據下標來說

    arr.remove(0) // (89,5,90.0,13)
    println("--------刪除後的元素遍歷---------------")
    for (i <- arr) {
      println(i)
    }
    println("最新的長度=" + arr.length) // 4

  }
}

  10.5.1 變長數組分析小結 

      1) ArrayBuffer是變長數組,類似Java的ArrayList

      2) val arr = ArrayBuffer[Int]() 也是使用apply方法構建對象

      3) def append(elems: A*) { appendAll(elems) } 接收的是可變參數

      4) 每append一次,arr在底層會重新分配空間,進行擴容,arr的記憶體地址會發生變化,也就成為新的ArrayBuffer

  10.5.2 定長數組與變長數組的轉換 

      -說明

        在開發中,我們可能使用對定長數組和變長數組進行轉換

          arr1.toBuffer //定長數組轉可變數組

          arr2.toArray //可變數組轉定長數組

      -註意事項

        arr1.toBuffer 返回結果才是一個可變數組,arr1本身沒有變化

        arr2.toArray 返回結果才是一個定長數組,arr2本身沒有變化

      -案例演示

import scala.collection.mutable.ArrayBuffer

object boke_demo01 {

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

    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)

  }
}

  10.5.3 多維數組的定義和使用 

      -說明

        //定義

        val arr = Array.ofDim[Double](3,4)

        //說明:二維數組中有三個一維數組,每個一維數組中有四個元素

        //賦值

        aar(1)(1) = 9.6

      -案例演示

object boke_demo01 {

  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) = 9

    //遍歷
    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()

    }
  }
}

10.6 數組-Scala數組與Java的List的互轉

  10.6.1 Scala數組轉Java的List 

      在開發中,有時需要我們將Scala數組轉成Java數組

  10.6.2 案例演示 

import scala.collection.mutable.ArrayBuffer

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    
    // 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]

  }
}

  10.6.3 Java的List轉Scala數組(mutable.Buffer) 

      -案例演示

 //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)

10.7 元組Tuple-元組的基本使用 

  10.7.1 基本介紹 

      元組也是可以理解為一個容器,可以存放各種相同或者不同類型的數據。說得簡單點,就是將多個無關的數據封裝為一個整體,稱為元組。特點靈活,對數據沒有過多的約束。註意:元組中最多只能有22個元素

  10.7.2 元組的創建 

      -案例演示

object boke_demo01 {

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

    //創建
    //說明 1. tuple 就是一個 Tuple 類型是 Tuple5
    //簡單說明: 為了高效的操作元組 , 編譯器根據元素的個數不同,對應不同的元組類型 // 分別 Tuple1----Tuple22
    val tuple = (1, 2, 3, "hello", 4)
    println(tuple)
  }
}

      -對案例演示的說明 

        1) tuple的類型是Tuple5類,是Scala特有的類型

        2) tuple的類型取決於tuple後面有多少個元素,有對應關係,比如:4個元素 -> Tuple4

        3) 看一個Tuple5類的定義

final case class Tuple5[+T1, +T2, +T3, +T4, +T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5) extends Product5[T1, T2, T3, T4, T5] {
      override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + ")"
}

        4) 元組中最多只能有22個元素,即Tuple1 -> Tuple22

10.8 元組Tuple-元組數據的訪問 

  10.8.1 基本介紹 

      訪問元組中的數據,可以採用順序號(_順序號),也可以通過索引(productElement)訪問

  10.8.2 應用案例 

object boke_demo01 {

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

    //訪問元組
    val t1 = (1, "a", "b", true, 2)
    println(t1._1) // 1 //訪問元組的第一個元素 ,從 1 開始

    println(t1.productElement(0)) // 1 // 訪問元組的第一個元素,從 0 開始
  }
}

10.9 元組Tuple-元組數據的遍歷  

      Tuple是一個整體,遍歷需要調其迭代器

object boke_demo01 {

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

    val t1 = (1, "a", "b", true, 2)

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

10.10 列表List-創建List 

  10.10.1 基本介紹 

      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]

  10.10.2 創建List的應用案例 

object boke_demo01 {

  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, "Hello") //創建時,直接分配元素
    println(list01)

    val list02 = Nil //空集合
    println(list02)

  }
}

  10.10.3 創建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

10.11 列表List-訪問List元素 

    //訪問 List 的元素
    val value1 = list01(1) // 1 是索引,表示取出第 2 個元素
    println("value1=" + value1) // 2

10.12 列表List-元素的追加 

  10.12.1 接本介紹 

      向列表中增加元素,會返回新的列表/集合對象。註意:Scala中List元素的追加形式非常獨特,和Java不一樣

  10.12.2 方式1-在列表的最後增加數據 

      -案例演示

  10.12.3 方式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)

  10.12.4 方式3-在列表的最後增加數據 

      -說明

        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)

10.13 ListBuffer 

  10.13.1 基本介紹 

      ListBuffer是可變的list集合,可以添加,刪除元素,ListBuffer屬於序列

      //追一下繼承關係即可

      Seq var listBuffer = ListBuffer(1,2)

  10.13.2 案例演示 

import scala.collection.mutable.ListBuffer

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    //創建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
    }

  }
}

10.14 隊列Queue-基本介紹 

  10.14.1 隊列的說明 

      1) 隊列是一個有序列表,在底層可以用數組或是鏈表來實現

      2) 其輸入和輸出要遵循先入先出的原則。即:現存入隊列的數據,要先取出。後存入的要後取

      3) 在Scala中,由設計者直接給我們提供隊列類型Queue使用

      4) 在Scala中,有scala.collection.mutable.Queue 和 scala.collection.immutable.Queue,一般來說,在開發中通常使用可變集合中的隊列

10.15 隊列Queue-隊列的創建 

import scala.collection.mutable

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    //創建隊列
    val q1 = new mutable.Queue[Int]
    println(q1)

  }
}

10.16 隊列Queue-隊列元素的追加數據 

import scala.collection.mutable

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    //創建隊列
    val q1 = new mutable.Queue[Int]

    //給隊列增加元素
    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) 作為一個元素加入到隊列中

  }
}

10.17 隊列Queue-刪除和加入隊列元素 

      在隊列中,嚴格地遵守,入隊列的數據,放在隊尾,出隊列的數據是從隊列頭部取出

    //dequeue 從隊列的頭部取出元素 q1 本身會變
    val queueElement = q1.dequeue()
    println("queueElement=" + queueElement + "q1="+q1)
    //enQueue 入隊列,預設是從隊列的尾部加入.
    q1.enqueue(96,101,201,666)
    println("q1=" + q1) // Queue(4, 5, 7, 96,101,201,666)

10.18 隊列Queue-返回隊列的元素 

    //隊列 Queue-返回隊列的元素
    //1. 獲取隊列的第一個元素
    println(q1.head) // 4, 對 q1 沒有任何影響
    //2. 獲取隊列的最後一個元素
    println(q1.last) // 666, 對 q1 沒有任何影響
    //3. 取出隊尾的數據 ,即:返回除了第一個以外剩餘的元素,可以級聯使用
    println(q1.tail) // (5, 7, 96,101,201,666)
    println(q1.tail.tail.tail.tail) // (101,201,666)

10.19 映射Map-基本介紹

  10.19.1 Java中Map回顧  

      HashMap是一個散列表(數組+鏈表),它存儲的內容是鍵值對(key-value)映射,Java中的HashMap是無序的,key不能重覆

  10.19.2 案例演示 

import java.util.HashMap;

public class JavaHashMap {
    public static void main(String[] args) {

        HashMap<String,Integer> hm = new HashMap();
        hm.put("no1", 100);
        hm.put("no2", 200);
        hm.put("no3", 300);
        hm.put("no4", 400);
        hm.put("no1", 500); //更新

        System.out.println(hm);//無序的
        System.out.println(hm.get("no2"));

    }
}

  10.19.3 Scala中的Map介紹 

      1) Scala中的Map和Java類似,也是一個散列表,它存儲的內容也是鍵值對(key-value)映射,Scala中不可變的Map是有序的,可變的Map是無序的

      2) Scala中,有可變Map(scala.collection.mutable.Map)和不可變Map(scala.collection.immutable.Map)

10.20 映射Map-構建Map 

  10.20.1 方式1-構造不可變映射 

      Scala中的不可變Map是有序的,構建Map中的元素底層是Tuple2類型

      案例演示

object boke_demo01 {

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

    //方式1-構造不可變映射
    //1.預設Map是 immutable.Map
    //2.key-value 類型支持Any
    //3.在Map的底層,每對key-value是Tuple2
    //4.從輸出的結果看到,輸出順序和聲明順序一致
    val map1 = Map("Alice" -> 19, "Tom" -> 20, "Jack" -> 21)
    println(map1)
  }
}

  10.20.2 方式2-構造可變映射 

    //方式2-構造可變映射
    //1.從輸出的結果看到,可變的map輸出順序和聲明順序不一致
    val map2 = mutable.Map("Alice" -> 19, "Tom" -> 20, "Jack" -> 21)
    println(map2)

  10.20.3 方式3-創建空的映射 

    val map3 = new scala.collection.mutable.HashMap[String, Int]
    println(map3)

  10.20.4 方式4-對偶元組 

      -說明

        即創建包含鍵值對的二元組,和第一種方式等價,只是形式上不同而已

        對偶元組就是只含有兩個數據的元組

      -案例演示

    //方式 4-對偶元組
    val map4 = mutable.Map(("Alice" , 19), ("Tom" , 20), ("Jack" , 21))
    println("map4=" + map4)

10.21 映射Map-取值 

  10.21.1 方式1-使用map(key) 

    val value1 = map2("Alice") 
    println(value1)

       -說明

        1) 如果key存在,則返回對應的值

        2) 如果key不存在,則拋出異常[java.util.NoSuchElementException]

        3) 在Java中,如果key不存在則返回null

        4) 案例演示

    //方式 1-使用 map(key)
    println(map4("Alice")) // 19
    // 拋出異常(java.util.NoSuchElementException: key not found:)
    //println(map4("Alice~"))

10.21.2 方式2-使用contains方法檢查是否存在key 

    // 返回 Boolean
    // 1.如果 key 存在,則返回 true
    // 2.如果 key 不存在,則返回 false
    map4.contains("T")

      -說明 

        使用contains先判斷再取值,可以防止異常,並加入相應的處理邏輯

      -案例演示

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

  10.21.3 方式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

      -案例演示

    //方式 3-使用 map.get(key).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) // 拋出異常

  10.21.4 方式4-使用map.getOrElse()取值 

      -getOrElse方法:def getOrElse[V1 >: V](key: K, default :=> V1)

      -說明

        1) 如果key存在,返回key對應的值

        2) 如果key不存在,返回預設值。在Java中底層有很多類似的操作

        3) 案例演示

    //方式 4-使用 map4.getOrElse()取值
    println(map4.getOrElse("Alice~~~","預設的值:愛麗絲"))

  10.21.5 如何選擇取值的方式 

      1) 如果我們確定map有這個key,則應當使用map(key),速度快

      2) 如果我們不確定map是否有這個key,而且有不同的業務邏輯,使用map.contains(),先判斷再加入邏輯

      3) 如果只是簡單的希望得到一個值,使用map.getOrElse("ip","127.0.0.1")

10.22 映射Map-對map修改、添加和刪除 

  10.22.1 更新map的元素  

      -案例演示

    val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
    map5("Alice") = 20 //更新
    println("map5=" + map5)

      -小結

        1) map是可變的,才能修改,否則報錯

        2) 如果key存在:則修改對應的值,key不存在,等價於添加一個key-value

  10.22.2 添加map元素  

      -方式1-增加單個元素

    val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
    map5 += ("史瑞克" -> 27) //增加
    println("map5=" + map5)

       -方式2-增加多個元素

    val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
    map5 += ("史瑞克" -> 27, "滅霸" -> 100)
    println("map5=" + map5)

       -說明:當增加一個key-value,如果key存在就是更新,如果不存在就是添加

  10.22.3 刪除map元素 

      -案例演示

    val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
    map5 += ("史瑞克" -> 27, "滅霸" -> 100)
    map5 -= ("Alice","Tom","Ja")
    println("map5=" + map5)

      -說明

        1) “Alice”,“Tom”就是要刪除的key,可以寫多個

        2) 如果key存在,就刪除,如果key不存在,也不會報錯

10.23 映射Map-對map遍歷 

      對map的元素(元組Tuple2對象)進行遍歷的方式很多,具體如下:

import scala.collection.mutable

object boke_demo01 {

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

    val map1 = mutable.Map( ("A", 1), ("B", 2), ("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)
  }
}

      -說明

        1) 每遍歷一次,返回的元素是Tuple2

        2) 取出的時候,可以按照元組的方式來取

      -案例演示

import scala.collection.mutable

object boke_demo01 {

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

    //map 的遍歷
    val map6 = mutable.Map(("A", 1), ("B", 2), ("C", 3))
    println("----(k, v) <- map6--------")
    for ((k, v) <- map6) println(k + " is mapped to " + v)

    println("----v <- map6.keys--------")
    for (v <- map6.keys) println(v)

    println("----v <- map6.values--------")
    for (v <- map6.values) println(v)

    //這樣取出方式 v 類型是 Tuple2
    println("----v <- map6--------")
    for (v <- map6) println(v + " key =" + v._1 + " val=" + v._2)
  }
}

10.24 集Set-基本介紹 

      集是不重覆元素的結合,集不保留順序,預設是以哈希集實現

  10.24.1 Java中Set的回顧 

      Java中,HashSet是實現Set<E>介面的一個實體類,數據是以哈希表的形式存放的,裡面不能包含重覆數據。Set介面是一種不包含重覆元素的collection,HashSet中的數據也是沒有順序的

  10.24.2 案例演示 

import java.util.HashSet;

public class JavaHashSet {
    public static void main(String[] args) {
        //java中的Set的元素 沒有順序,不能重覆
        HashSet hs = new HashSet<String>();
        hs.add("Jack");
        hs.add("Tom");
        hs.add("Alice");
        hs.add("史瑞克");
        System.out.println(hs);

    }
}

      預設情況下,Scala使用的是不可變集合,如果想要使用可變集合,需要引用scala.collection.mutable.Set包

10.25 集Set-創建

import scala.collection.mutable

object boke_demo01 {

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

    val set = Set(1, 2, 3) //不可變
    println(set)

    val set2 = mutable.Set(1, 2, "hello") //可以變
    println("set2" + set2)
    
  }
}

10.26 集Set-可變集合的元素添加和刪除 

  10.26.1 可變集合的元素添加 

    mutableSet.add(4) //方式 1
    mutableSet += 6 //方式 2
    mutableSet.+=(5) //方式 3

      -說明:如果添加的對象已經存在,則不會重覆添加,也不會報錯 

  10.26.2 可變集合的元素刪除 

    val set3 = mutable.Set(1,2,3,"abc")
    set3 -= 2 // 操作符形式
    set3.remove("abc") // 方法的形式,scala 的 Set 可以直接刪除值
    println(set3)
    //說明:如果刪除的對象不存在,則不生效,也不會報錯

  10.26.3 Set集合的遍歷操作

    val set4 = mutable.Set(1, 2, 3, "abc")
    for (x <- set4) {
      println(x)
    }

10.27 集Set-更多操作 

 

   


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ###15Collection-List-ArrayList/LinkedList/* * Collection介面中的方法* A:添加功能* boolean add(Object obj):把obj這個元素,添加到集合中去* boolean addAll(Collection c):將 c 這個集 ...
  • 前言:近段時間學習R語言用到最多的數據格式就是data.frame,現對data.frame常用操作進行總結,其中函數大部分來自dplyr包,該包由Hadley Wickham所作,主要用於數據的清洗和整理。 一、創建 data.frame創建較為容易,調用data.frame函數即可。本文創建一個 ...
  • 基於flask的網頁聊天室(一) 基本目標 基於flask實現的web聊天室,具有基本的登錄註冊,多人發送消息,接受消息 擴展目標 除基本目標外添加當前線上人數,消息回覆,markdown支持,歷史消息等 創建項目 首先創建基本的文件結構: auth和chat通過藍圖建立: 例如auth: from ...
  • 今天老師又沒有講新課,不過講了練習題,擴展了一下我們的思維。 今天就講一下如何獲取時間吧。 代碼: //一般在程式開頭寫一個,結尾寫一個,用結尾的減開頭, //就能算出這個程式運行的時間 今天就這些啦!!! 下周講JDBC,有點期待,喝喝喝!!! 字數不夠,發不了首頁,雖然每天都被首頁踢出來。喝喝喝 ...
  • Mac OS下修改Python的鏡像源 步驟: 切換到家目錄 創建目錄 .pip 並切換到該目錄 創建 pip.conf 文件並寫入配置信息 以上採用的是 清華大學 的鏡像源,經過測試比較穩定 也可以用其他: 清華:https://pypi.tuna.tsinghua.edu.cn/simple 阿 ...
  • apache配置文件httpd.conf修改“AddType application/x-httpd-php .xxx”,“.xxx”是想要的尾碼名。 把文件尾碼改成自定義的尾碼名。 phpStorm為防止報錯,在Settings->File Types->Recognized File Types ...
  • Kafka集群搭建分為單節點的偽分散式集群和多節點的分散式集群兩種,首先來看一下單節點偽分散式集群安裝。單節點偽分散式集群是指集群由一臺ZooKeeper伺服器和一臺Kafka broker伺服器組成,如下圖所示: 為了搭建單節點Kafka集群,需要依次安裝如下軟體:安裝Java-->安裝ZooKe ...
  • 什麼是ABA? ABA的危害? ABA的解決方法? AtomicStampedReference是什麼? AtomicStampedReference是怎麼解決ABA的? ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...