scala集合(陣列,序列,集合,元組,對映)
1 Array陣列
陣列分為不可變長陣列(Array) 和可變長陣列(ArrayBuffer) 。 如字面意思,前者長度不可變, 已經寫死了, 後者長度可變。注:只是長度不可變, 但是對應角標元素可變 。
/**
* 在Scala中,陣列分為不可變長陣列(在immutable包下)和可變長陣列 (在mutable下)
* 不可變長陣列:長度不可變,角標元素值可變
* 可變長陣列:長度可變,角標元素值可變
*/
不可變長陣列(Array)
在Scala中, Array代表的含義與Java中類似, 也是長度不可改變的陣列。 此外,由於Scala與Java都是執行在JVM中, 雙方可以互相呼叫, 因此Scala
/** * 不可變長陣列 */ //[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。
如果不想每次都使用全限定名, 則可以預先匯入ArrayBuffer類import 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
陣列的轉換操作
flatMap, map, flatten, filter, sortBy.... /**
* 陣列的轉換操作
*/
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)