1. 程式人生 > >Scala中的集合

Scala中的集合

 作者:林偉兵,叩丁狼教育高階講師,原創文章,未經同意不得隨意轉載

1. 定長陣列

陣列的建立:

//通過指定陣列長度來建立陣列,系統會為其賦上預設的值
scala> new ArrayString
res0: Array[String] = Array(null, null, null, null, null)
scala> new ArrayDouble
res1: Array[Double] = Array(0.0, 0.0, 0.0, 0.0, 0.0)
//如果想在建立的時候指定元素的內容,可以呼叫陣列伴生物件的的apply方法
scala> Array("Hadoop","Storm","Spark")
res2: Array[String] = Array(Hadoop, Storm, Spark)

陣列的操作包含了對元素的讀寫,陣列的長度 求最大值最小值等,除此之外還可以列印陣列的長度:

//存值取值的操作
scala> res0(2)
res3: String = null
scala> res0(2) = "Hello world"
scala> res0
res5: Array[String] = Array(null, null, Hello world, null, null)
scala> Array(1,2,3,4,5,6,0)
res6: Array[Int] = Array(1, 2, 3, 4, 5, 6, 0)
//求極限值 求和
scala> res6.min
res7: Int = 0
scala> res6.max
res8: Int = 6
scala> res6.sum
res9: Int = 21

如果想列印一個數組內容,預設的toString是無法實現的,可以使用mkString來實現列印, 如下:

scala> res6.toString
res14: String = [[email protected]
scala> res6.mkString
res10: String = 1234560
scala> res6.mkString(",")
res11: String = 1,2,3,4,5,6,0
scala> res6.mkString("<",",",">")
res12: String = <1,2,3,4,5,6,0>

2. 變長陣列

定長陣列指的是陣列的長度不變,而變長陣列指的是長度可以變。變長陣列使用scala.collection.mutable.ArrayBuffer 來導包實現,如下程式碼:

//在客戶端 如果沒有導包會出現找不到類異常
scala> new ArrayBufferInt
<console>:12: error: not found: type ArrayBuffer
       new ArrayBufferInt
           ^

scala> import scala.collection.mutable.ArrayBuffer
//建立一個空的變長陣列
scala> new ArrayBufferInt
res16: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

變長陣列的用法與定長用法一致,只不過多了對元素的增減操作:

//可以單獨新增一個元素
scala> res16 += 3
scala> res16 += 7
scala> res16 += 10
res19: res16.type = ArrayBuffer(3, 7, 10)

//也可以新增多個元素
scala> res16 += (4,5,6)
res20: res16.type = ArrayBuffer(3, 7, 10, 4, 5, 6)

//也可以新增一個數組
scala> res16 ++= Array(4,5,6)
res21: res16.type = ArrayBuffer(3, 7, 10, 4, 5, 6, 4, 5, 6)

//移除陣列元素
scala> res16.remove(0)
res23: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(7, 10, 4, 5, 6, 4, 5, 6)
scala> res16.remove(0,3)
res25: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(5, 6, 4, 5, 6)

//修改元素
scala> res16(2) = 6
res27: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(5, 6, 6, 5, 6)

3. 變長陣列轉為定長陣列

如下展示了變長陣列轉為定長陣列:

scala> ArrayBuffer("hadoop","spark","storm")
scala> res0.toArray
res1: Array[String] = Array(hadoop, spark, storm)

4. List&ListBuffer

4.1 不可變List操作用如下:

//如果想建立一個空List 可以使用Nil來實現
scala> Nil
res0: scala.collection.immutable.Nil.type = List()

//也可以使用伴生物件的apply來實現建立
scala> val list1 = List(1,2,3,4,5)
list1: List[Int] = List(1, 2, 3, 4, 5)

//.head可以獲取List的頭部
scala> list1.head
res1: Int = 1

//.tail可以獲取List的尾部(這裡的尾部就是除了頭部以外的所有其他元素)
scala> list1.tail
res2: List[Int] = List(2, 3, 4, 5)

//將一個物件加入到後面列表的頭部

scala> val list2 = 1 :: Nil
list2: List[Int] = List(1)
scala> val list2 = 1 :: 2 :: 3 :: Nil
list2: List[Int] = List(1, 2, 3)
scala> val list3 = 55 :: list2
list3: List[Int] = List(55, 1, 2, 3)

4.2 ListBuffer 的操作與 ArrayBuffer 的操作思想差不多。程式碼如下:

scala> import scala.collection.mutable.ListBuffer

//建立ListBuffer
scala> new ListBuffer[Int]

//新增一個元素
scala> res4 += 2
scala> res4 += 3
res6: res4.type = ListBuffer(2, 3)

//新增多個元素
scala> res4 += (2,5,6,7,4)
res7: res4.type = ListBuffer(2, 3, 2, 5, 6, 7, 4)

//新增一個佇列
scala> res4 ++= List(9,9,9)
res9: res4.type = ListBuffer(2, 3, 2, 5, 6, 7, 4, 9, 9, 9)

//刪除元素
scala> res4 -= 2
res11: res4.type = ListBuffer(3, 2, 5, 6, 7, 4, 9, 9, 9)
scala> res4 -= (9,9)
res12: res4.type = ListBuffer(3, 2, 5, 6, 7, 4, 9)
scala> res4 --= List(5,6,7)
res13: res4.type = ListBuffer(3, 2, 4, 9)

//變長ListBuffer轉定長List
scala> res4.toList
res14: List[Int] = List(3, 2, 4, 9)

//變長ListBuffer轉定長Array
scala> res4.toArray
res15: Array[Int] = Array(3, 2, 4, 9)

5. 可變&不可變Map

以示例驅動為準,如下是對不可變Map的操作:

// 建立一個Map物件
scala> Map("xiaoming" -> 85, "xiaohong" -> 99)
res1: scala.collection.immutable.Map[String,Int] = Map(xiaoming -> 85, xiaohong -> 99)

// 取值操作
scala> res1("xiaoming")    // res2: Int = 85

// 不可變Map是無法插入新值的
scala> res1("xiaozhang") = 77
<console>:13: error: value update is not a member of scala.collection.immutable.Map[String,Int]
       res1("xiaozhang") = 77

// Map常見的兩種遍歷模式:
scala> for ((k1,v1) <- res1 ) println(k1+" : "+v1)
xiaoming : 85
xiaohong : 99

scala> for ( k1 <- res1.keySet ) println(k1+" : "+ res1(k1))
xiaoming : 85
xiaohong : 99

為了解決擴充套件Map的需求,就需要使用可變的Map,使用如下:

//建立可變Map的兩種方式,HashMap是Map的一個子類實現
scala> scala.collection.mutable.Map("xiaoming" -> 85)
res6: scala.collection.mutable.Map[String,Int] = Map(xiaoming -> 85)
scala> scala.collection.mutable.HashMapString,Int
res9: scala.collection.mutable.HashMap[String,Int] = Map()

//對可變Map進行存值操作
scala> res6("xiaohong") = 95
scala> res6
res8: scala.collection.mutable.Map[String,Int] = Map(xiaohong -> 95, xiaoming -> 85)

對於取值,這裡需要注意的是預設情況下,如果找不到對應的key是會報錯的:

scala> res6("xiaoli")
java.util.NoSuchElementException: key not found: xiaoli
  at scala.collection.MapLike$class.default(MapLike.scala:228)
  at scala.collection.AbstractMap.default(Map.scala:59)
  at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
  ... 32 elided

scala> res6.getOrElse
getOrElse   getOrElseUpdate
scala> res6.getOrElse("xiaoli",-1)
res12: Int = -1

對於取的操作,有可能去得到值有可能取不到;當呼叫get方法的時候返回的有兩種情況,我們稱之為Option,當取得到值返回Some,當取不到值返回None:

scala> Map("xiaoming" -> 85, "xiaozhang" -> 96)
res0: scala.collection.immutable.Map[String,Int] = Map(xiaoming -> 85, xiaozhang -> 96)
scala> res0.get("xiaoli")
res2: Option[Int] = None
scala> res0.get("xiaozhang")
res3: Option[Int] = Some(96)

// 當不確定返回Some還是None時為進一步取到具體的值
scala> res0.get("xiaozhang1").getOrElse(-1)
res6: Int = -1

6. Tuple元組簡單應用

​ 與列表一樣,元組也是不可變的,但與列表不同的是元組可以包含不同型別的元素。元組的值是通過將單個的值包含在圓括號中構成的。例如:

scala> val myTuple = (1,2,3,'a','b','c')
myTuple: (Int, Int, Int, Char, Char, Char) = (1,2,3,a,b,c)
scala> myTuple._4
res0: Char = a

// 元組的元素是無法賦值的
scala> myTuple._4 = 'k'
<console>:12: error: reassignment to val