Scala集合操作—List
Scala中列表是非常類似於陣列,這意味著,一個列表的所有元素都具有相同的型別,但有兩個重要的區別。首先,列表是不可變的,這意味著一個列表的元素可以不被分配來改變(在官方文件中List是immutable的,所以對List的所謂增上改查都是產生新的物件,並非在原來的集合上改動)。第二,列表表示一個連結串列,而陣列平坦的。通常來說有以下幾個常用點選開啟連結操作是必須掌的:
1.增刪改查單個元素
2.單個集合的各種遍歷方式
3.單個集合分拆組合與翻轉
4.兩個集合的拼接,刪除等操作
執行結果:<span style="font-family:Times New Roman;font-size:14px;"> /** * 1.增刪改查單個元素 */ val list = List("scala","spark","hadoop") println("test"::list) // 增 (返回新物件,源物件不變) println(list(0)) //取 println(list apply 0) //取 (同上) //list(3) ="hadoop1";// 改 error (不能修改imutable的集合) println(list .updated(2,"hadoop1")) //it works println(list.last) //取最後一個元素</span>
<span style="font-family:Times New Roman;font-size:14px;"> List(test, scala, spark, hadoop)
scala
scala
List(scala, spark, hadoop1)
hadoop</span>
<span style="font-family:Times New Roman;font-size:14px;"> /** * 2.單個集合的各種遍歷方式 */ val lst = List(1,2,3,4,5); print("foreach遍歷:") lst.foreach { x => print(x+",")} //foreach遍歷,這個是傳統遍歷,新手不熟無奈之下可以用它 println("") var temp = lst.map { x => x+1 } //遍歷,與foreach的區別是返回值為List【B】 println("map遍歷:"+temp.mkString(",")); var temp1 = lst.reduceLeft((sum,i)=>sum +i) //遍歷,返回值型別是一個與集合相同的Int println("reduce遍歷返回Int:"+temp1); var temp2 = lst.foldLeft(List[Int]())((x,y)=>y::x); //遍歷,返回值是自定義型別 //ps fold類函式還可以改成 :\ ,/:的形式,程式碼精簡了不少,但是可讀性卻減低了例如 println("foldLeft遍歷返回自定義型別:"+temp2.mkString(",")); var temp3=( List[Int]() /: lst){(m,c)=>c::m} //遍歷,實現反轉 println("foldLeft遍歷實現反轉:"+temp2.mkString(",")); </span>
<span style="font-family:Times New Roman;font-size:14px;"><strong> 執行結果:</strong></span>
<pre name="code" class="plain"><span style="font-family:Times New Roman;font-size:14px;"> foreach遍歷:1,2,3,4,5, map遍歷:2,3,4,5,6 reduce遍歷返回Int:15 foldLeft遍歷返回自定義型別:5,4,3,2,1 foldLeft遍歷實現反轉:5,4,3,2,1</span>
<span style="font-family:Times New Roman;font-size:14px;"> /**
* 3.單個集合的拆分組合與反轉
*/
val list = List(1,2,3,4,5);
//除了最後一個元素之外的所有元素 (用法有點怪)
println(list.init+"----init除了最後一個元素之外的所有元素")
//除了第一個元素之外的所有元素 (用法有點怪)
println(list.tail+"----tail除了第一個元素之外的所有元素")
//生成迭代物件,注意區分init
println(list.inits+"----inits生成迭代物件,注意區分init")
val data = List('a','b','c','d','e')
//取前n個元素
var take = data take 2
println(take.mkString(",")+"-----take取前n個元素 ")
//除去前n個元素
var drop = data drop 2
println(drop.mkString(",")+"-----drop除去前n個元素 ")
//返回元素的索引
println(data.indices+"----indices返回元素的索引 ")
//索引和資料組合長Tuple
var t = data.indices zip data
println(t.mkString(" ") +"----zip索引和資料組合長Tuple")
//資料和索引組合
println(data.zipWithIndex+"----zipWithIndex資料和索引組合")
//grouped 分組
println(data.grouped(2).mkString(",")+"-----grouped分組");
</span>
<span style="font-family:Times New Roman;font-size:14px;"><strong>執行結果:</strong> </span>
<pre name="code" class="plain"><span style="font-family:Times New Roman;font-size:14px;">List(1, 2, 3, 4)----init除了最後一個元素之外的所有元素
List(2, 3, 4, 5)----tail除了第一個元素之外的所有元素
non-empty iterator----inits生成迭代物件,注意區分init
a,b-----take取前n個元素
c,d,e-----drop除去前n個元素
Range(0, 1, 2, 3, 4)----indices返回元素的索引
(0,a) (1,b) (2,c) (3,d) (4,e)----zip索引和資料組合長Tuple
List((a,0), (b,1), (c,2), (d,3), (e,4))----zipWithIndex資料和索引組合
List(a, b),List(c, d),List(e)-----grouped分組 </span>
<span style="font-family:Times New Roman;font-size:14px;">
</span>
<span style="font-family:Times New Roman;font-size:14px;"> /**
* 4.集合間的連結互動
*/
val left = List(1,2,3)
val right = List(4,5,6)
//以下操作等價
println(left ++ right) // List(1,2,3,4,5,6)
println(left ++: right) // List(1,2,3,4,5,6)
println(right.++:(left)) // List(1,2,3,4,5,6)
println(right.:::(left)) // List(1,2,3,4,5,6)
println(right:::left) // List(1,2,3,4,5,6)
//以下操作等價
println(0 +: left) //List(0,1,2,3)
println(left.+:(0)) //List(0,1,2,3)
//以下操作等價
println(left :+ 4 ) //List(1,2,3,4)
println(left.:+(4) ) //List(1,2,3,4)
//以下操作等價
println(0 :: left ) //List(0,1,2,3)
println(left.::(0) ) //List(0,1,2,3)
</span>
執行結果:
<pre name="code" class="plain" style="color: rgb(102, 102, 102);"><span style="font-family:Times New Roman;font-size:14px;">List(1, 2, 3, 4, 5, 6)
List(1, 2, 3, 4, 5, 6)
List(1, 2, 3, 4, 5, 6)
List(1, 2, 3, 4, 5, 6)
List(4, 5, 6, 1, 2, 3)
List(0, 1, 2, 3)
List(0, 1, 2, 3)
List(1, 2, 3, 4)
List(1, 2, 3, 4)
List(0, 1, 2, 3)
List(0, 1, 2, 3)</span>
<span style="font-family:Times New Roman;font-size:14px;">
</span>
總結:
++ :[B](that: GenTraversableOnce[B]): List[B] 從列表的尾部新增另外一個列表
++: :[B >: A, That](that: collection.Traversable[B])(implicit bf: CanBuildFrom[List[A], B, That]): That 在列表的頭部新增一個列表
+: :(elem: A): List[A] 在列表的頭部新增一個元素
:+ :(elem: A): List[A] 在列表的尾部新增一個元素
:: :(x: A): List[A] 在列表的頭部新增一個元素
::: :(prefix: List[A]): List[A] 在列表的頭部新增另外一個列表
:\ :B](z: B)(op: (A, B) ⇒ B): B 與foldRight等價
看到這裡大家應該跟我一樣有一點暈吧,怎麼這麼多奇怪的操作符,這裡給大家一個提示,任何以冒號結果的操作符,都是右繫結的,即 0 :: List(1,2,3) = List(1,2,3).::(0) = List(0,1,2,3) 從這裡可以看出操作::其實是右邊List的操作符,而非左邊Int型別的操作符