1. 程式人生 > >scala集合(陣列,序列,集合,元組,對映)

scala集合(陣列,序列,集合,元組,對映)

1 Array陣列

陣列分為不可變長陣列(Array) 和可變長陣列(ArrayBuffer) 。 如字面意思,前者長度不可變, 已經寫死了, 後者長度可變。:只是長度不可變, 但是對應角標元素可變 。

/**
 * 在Scala中,陣列分為不可變長陣列(在immutable包下)和可變長陣列 (在mutable下)
 * 不可變長陣列:長度不可變,角標元素值可變
 * 可變長陣列:長度可變,角標元素值可變
 */

不可變長陣列(Array

Scala中, Array代表的含義與Java中類似, 也是長度不可改變的陣列。 此外,由於ScalaJava都是執行在JVM中, 雙方可以互相呼叫, 因此Scala

陣列的底層實際上是Java陣列。 例如字串陣列在底層就是JavaString[], 整數陣列在底層就是JavaInt[] 。

/**
     * 不可變長陣列
     */
    //[Int]相當於java中的泛型<Int>,起到元素型別保護的作用
    val arr1 = Array[Int](1, 2, 3, 4)
    //如果一個數組中,有多個不同值型別的元素,那麼這個陣列的型別是這些元素型別的公共父型別Any
    val arr2: Array[Any] = Array("true", false, 100, 'a')
    //定義了一個數組,長度為5,初始值與泛型的初始值一致,也就是0
    val arr3 = new Array[Int](5)
    //    println(arr3.toBuffer)//ArrayBuffer(0, 0, 0, 0, 0)
    //定義了一個數組,長度為1,值為5
    val arr4 = Array(5)
    //    println(arr4.toBuffer)//ArrayBuffer(5)

    arr1(0) = 100
    //    println(arr1.toBuffer)

    //++ 運算子:將兩個數組合併成一個新的陣列,原陣列不改變
    val arr5 = arr1 ++ arr2
    //    println(arr5.toBuffer)

可變長陣列(ArrayBuffer

Scala中, 如果需要類似於Java中的ArrayList這種長度可變的集合類, 則可以使用ArrayBuffer

如果不想每次都使用全限定名, 則可以預先匯入ArrayBufferimport scala.collection.mutable.ArrayBuffer

// 使用ArrayBuffer()的方式可以建立一個空的ArrayBuffer
val b = ArrayBuffer[Int]()

// 使用+=操作符, 可以新增一個元素, 或者多個元素
// 這個語法必須要謹記在心! 因為spark原始碼裡大量使用了這種集合操作語法!
b += 1
b += (2, 3, 4, 5)

// 使用++=操作符, 可以新增其他集合中的所有元素 

/**
     * 可變陣列
     */
    val arr6 = ArrayBuffer[Int]()
    //+= 新增一個元素
    arr6 += (1)
    arr6 += (2)
    //++= 新增一個數組
    arr6 ++= Array(3, 4, 5)
    arr6 ++= ArrayBuffer(6, 7, 8)
    //新增多個元素
    arr6 append (9, 10)

    //移除陣列的一個元素值
    arr6 -= 1
    arr6 -= 10
    //移除一個數組
    arr6 --= Array(3, 5, 7)
    //根據下標移除
    arr6 remove (0)
    //從角標開始移除幾個元素
    arr6 remove (0, 2)
陣列常見操作

max,min,sum,mkString

/**
     * 陣列常用方法
     */
    
    val arr = Array(1,2,3,4,5,6)
//    println(arr.max)
//    println(arr.min)
//    println(arr.mkString)//123456
//    println(arr.mkString("|"))//1|2|3|4|5|6
//    println(arr.mkString("[", "|", "]"))//[1|2|3|4|5|6]
//    println(arr.reverse.toBuffer)//Array(1,2,3,4,5,6)-->Array(6,5,4,3,2,1)

陣列的遍歷操作

for ,foreach

陣列的轉換操作

flatMapmapflattenfiltersortBy....
   /**
     * 陣列的轉換操作
     */

    val arr7 = Array[Int](8,7,9,10,12)
//    arr7.map((x:Int)=> x*2).sortBy((x:Int)=>x).reverse.foreach((x:Int)=> println(x))
//    arr7.map(_ * 2).sortBy(x => x).reverse.foreach(println(_))
    
    val strArr = Array[String]("hello world","hello scala")
//    strArr.map((x:String) => {
//      val split = x.split(" ")
//      split
//    }).flatten.foreach(println(_))
//    strArr.map(_.split(" ")).flatten.foreach(println(_))
//    strArr.flatMap((x:String)=> x.split(" ")).map(x => (x,1)).foreach(println(_))
    strArr.flatMap(_.split(" ")).map((_,1)).foreach(println(_))

2 List序列

序列分為不可變長序列(List) 和可變長序列(ListBuffer)。不可變集合中新增新元素, 會生成一個新集合, 和不可變集合並不矛盾。給集合中新增元素一般都是從集合頭部新增, 或者從集合尾部新增。

/**
 * List序列
 * 分為變長和不可變長序列,底層是連結串列
 * 特點:有序,可重複,增刪快,查詢慢
 * 不可變長序列:長度和角標都不可變
 */
    /**
     * 不可變長序列
     */
    val list1 = List(1, 2, 3, 4)
    //++ 連線兩個list,形成一個新的list,原先的list不改變
    val list2 = list1 ++ List(6, 7, 8)
    //    println(list2.toBuffer)//ArrayBuffer(1, 2, 3, 4, 6, 7, 8)

    /**
     * 變長序列
     */
    val lb0 = ListBuffer[Int](1, 2, 3, 4)
    // += 新增元素
    lb0 += 4
    // ++= 新增一個List或ListBuffer
    lb0 ++= List(5, 6, 7)
    //append 新增多個元素
    lb0.append(8, 9, 10)
//    println(lb0.toBuffer) //ArrayBuffer(1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10)
    //對應移除
    lb0 -= 4
    lb0 --= List(5, 6, 7)
    lb0 remove (0)
//    println(lb0.toBuffer) //ArrayBuffer(2, 3, 4, 8, 9, 10)
    lb0 remove (0, 2)
//    println(lb0.toBuffer) //ArrayBuffer(4, 8, 9, 10)
    
    /**
     * list頭部新增元素
     */
    val list3 = List(4,5,6)
    //並不是將元素新增到list3中,而是list3和(1,2,3)進行了合併形成了一個新的list
    //注意,(1,2,3)作為一個整體和list3進行合併
    var newList = list3 .:: (1,2,3)//List((1,2,3), 4, 5, 6)
    newList = list3.+: (1,2,3)//List((1,2,3), 4, 5, 6)
    newList = (1,2,3) :: list3//List((1,2,3), 4, 5, 6)
    newList = (1,2,3) +: list3//List((1,2,3), 4, 5, 6)
    //這裡是將1,2,3元素
    newList = List(1,2,3) ++ list3//List(1, 2, 3, 4, 5, 6)
//    println(newList)
    
    /**
     * list尾部新增元素
     */
    val list4 = List(1,2,3)
    //將(7,8,9)作為一個整體與list4進行合併,插入到list4尾部,形成一個新的list
    var newList4 = list4.:+(7,8,9)//List(1, 2, 3, (7,8,9))
    //將7,8,9與list4合併,插入到list4尾部,形成一個新的list
    newList4 = list4 ++ List(7,8,9)//List(1, 2, 3, 7, 8, 9)
//    println(newList4)
    
    /**
     * 序列的常用操作方法
     */
    val list5 = List(1,2,3,4,5)
    //求和
    println(list5.sum)
    //最大值
    println(list5.max)
    //最小值
    println(list5.min)
    //第一個元素
    println(list5.head)//1
    //最後一個元素
    println(list5.last)//5
    //反轉序列,形成一個新list,原list不變
    println(list5.reverse)//List(5, 4, 3, 2, 1)
    //拼接
    println(list5.mkString)//12345
    println(list5.mkString("|"))//1|2|3|4|5
    println(list5.mkString("[", "|", "]"))//[1|2|3|4|5]
    
    /**
     * 轉換操作
     */
    val list6 = List(3,5,1,2,2,3,5,2)
    list6.map(_*2).filter(x => x>3).sortBy(x => x).distinct.reverse.foreach(println(_))

3 Set集合

也分為可變長和不可變長集合,特點:無序,不重複。元素雖然無放入順序, 但是元素在set中的位置是由該元素的HashCode決定的, 其位置其實是固定的。

    /**
     * 不可變長set集合
     */
    val set1 = Set(1,2,4)
    val set2 = set1 ++ Set(4,5,6)
    println(set2)//Set(5, 1, 6, 2, 4)
    
    /**
     * 可變長set集合
     */
    val set3 = scala.collection.mutable.Set(1,2,3)
    //+= 新增元素
    set3 += 4
    set3 += 5
    // ++= 後面跟一個set集合
    set3 ++= Set(4,5,6)
    set3 add(7)
    println(set3)//Set(1, 5, 2, 6, 3, 7, 4)
    
    set3 -= 3
    set3 --= Set(1,2,3)
    println(set3)//Set(5, 6, 7, 4)
    
    /**
     * 常用操作
     */
    println(set3.mkString("|"))
    println(set3.size)
    println(set3.head)
    println(set3.last)
    println(set3.max)
    
    /**
     * 轉換操作
     */
    set3.map(_ * 2).filter(_ < 5).foreach(println(_))
 

4 Tuple元組

對映是K/V對偶的集合, 對偶是元組最簡單的形式, 元組可以封裝多個不同型別的值, 注意元組的角標是從1 開始的 。

    //定義一個元組
    val t1 = ("小明", "男", 23)
    //元組的角標是從1開始
    println(t1._1 + ":" + t1._2 + "-" + t1._3)

    //只有兩個元素組成的元組,稱為對偶元組(key-value)
    val tuple2 = ("id", 124)
    println(tuple2._1 + ":" + tuple2._2)

    //可以將元組的單個元素單獨賦值給對應的變數
    val tuple3, (name, age, sex) = ("張三", 12, "男")
    println(tuple3)
    println(name)
    println(age)
    println(sex)

    //陣列的拉鍊操作轉換成元組,按角標序列一一對應
    val arr1 = Array("a", "b", "c")
    val arr2 = Array("A", "B", "C")
    val tuple = arr1 zip arr2
    println(tuple.toBuffer) //ArrayBuffer((a,A), (b,B), (c,C))

  

5 Map對映

對映就是java裡面的map, 裡面存放的是k-v型別的資料, 底層是hash表。scala預設匯入的是imutable包下面的Map對映, 它是不可變的(長度和對應的值都是不可變的)。
構建對映

構建對映有兩種方式, 一種是箭頭 ->, 一種是元組()

/**
     * 不可變長對映
     */
    //使用元組的形式定義map
    val map1 = Map(("a", "A"), ("b", "B"))
    //使用箭頭的形式
    val map2 = Map("a" -> "A", "b" -> "B", "c" -> "C")
    //兩者混合的形式
    val map3 = Map(("a" -> "A"), "b" -> "B")
    //++ 合併兩個map,形成一個新的map
    val map4 = map1 ++ map2
    //    println(map4)//Map(a -> A, b -> B, c -> C)

    /**
     * 可變長Map對映
     */
    val map5 = scala.collection.mutable.Map("a" -> "A")
    map5 put ("b", "B")
    map5 += ("c" -> "C", "d" -> "D")
    map5 += (("e", "E"), ("f" -> "F"))
    map5 ++= Map("j" -> "J")
    //    println(map5)//Map(e -> E, b -> B, j -> J, d -> D, a -> A, c -> C, f -> F)

    //移除map中的key
    map5 -= "a"
    map5 --= Set("b", "c")
    map5 remove ("d")
    //    println(map5)//Map(e -> E, j -> J, f -> F)

訪問Map的元素
// 獲取指定key對應的value,如果key不存在,會報錯
val a= map0("a")
val b= map0("b")
// contains函式檢查key是否存在
val a= if (map0.contains("a")) map0("a") else 0
// getOrElse函式
val a= ages.getOrElse("a", 0)

訪問Map的元素
// 獲取指定key對應的value,如果key不存在,會報錯
val a= map0("a")
val b= map0("b")
// contains函式檢查key是否存在
val a= if (map0.contains("a")) map0("a") else 0
// getOrElse函式
val a= ages.getOrElse("a", 0)


 /**
     * 常用操作方法
     */

    val map6 = Map("a" -> "A", "b" -> "B", "c" -> "C", "d" -> "D")
    //contains 判斷一個key是否存在,存在返回true,否則返回false
    println(map6.contains("a"))
    //獲取key對應的值,如果通過Map("key")獲取key對應的值,先要判斷key是否存在
    if (map6.contains("a")) println(map6("a"))
    //get 也可以獲取key對應的值,返回一個option型別的物件。option有兩個子類,Some和None,如果有key,則返回Some(Some物件中封裝了key對應的值,
    //可以通過Some的get方法獲取);如果沒有,則返回None物件
    println(map6.get("b")) //Some(B)
    println(map6.get("e")) //None

    val v1: Option[String] = map6.get("d")
    if (!v1.isEmpty) println(v1.get) else println(v1)

    //getOrElse 獲取key對應的value,如果key不存在,返回預設值
    val v2 = map6.getOrElse("f", 0)
    println(v2) //0

LinkedHashMap、SortedMap

/**
     * LinkedHashMap:插入有序,按照插入順序排序,底層是連結串列結構
     */
    val map7 = scala.collection.mutable.LinkedHashMap[String, String]()
    map7 += ("a" -> "A")
    map7 += ("c" -> "C")
    map7 += ("b" -> "B")
    map7 += ("2" -> "123")
    map7 += ("1" -> "123")
    //    println(map7)//Map(a -> A, c -> C, b -> B, 2 -> 123, 1 -> 123)

    /**
     * SortedMap 可以對key進行自動字典排序
     */
    val map8 = scala.collection.mutable.SortedMap[String, String]()
    map8 += ("a" -> "A")
    map8 += ("c" -> "C")
    map8 += ("b" -> "B")
    map8 += ("2" -> "123")
    map8 += ("1" -> "123")
    //    println(map8)//TreeMap(1 -> 123, 2 -> 123, a -> A, b -> B, c -> C)