Scala集合操作—List

时间:2023-01-31 11:18:05

      Scala常用操作:http://www.yiibai.com/scala/scala_lists.html

       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类型的操作符