scala 学习笔记——集合

来源:互联网 发布:大数据转型的企业 编辑:程序博客网 时间:2024/04/28 12:56

scala 学习笔记——集合

所有集合都扩展至特质Iterable。集合分为三类:

序列(seq):

有先后顺序的值的集合
  • 不可变序列:

Array/Vector(向量/数组), Range(整数序列), 这两种集合扩展了IndexSeq特质,可以通过下标迅速的访问任意元素。
List(列表/线性表),Queue(队列),Stack(栈),Stream(流)

  • 可变序列:

ArrayBuffer(数组缓冲),这种集合扩展了IndexSeq特质,可以通过下标迅速的访问任意元素。
Stack(栈),Queue(队列),Priority Queue(优先级队列),LikedList(链表),Double LikedList(双向链表)

列表List

列表是空表(Nil),或者是head+tail,这里tail又是一个列表。

val digits=List(4,2)  List(9,4,2).tail //(42)//digits.head值是4,digits.tail是List(2),digits.tail.head值是2,digita.tail.tail是Nil
//可以通过::操作符从给定的头或者尾创建一个新的列表。9::List(4,2) //就是List(9,4,2),他等同于(9::(4::(2::Nil)))

在C++或者JAVA中我们用迭代器来遍历链表,在scala中也可以这么做。但使用递归更加自然。

一个例子,计算列表之和:

def sum(lst: List[Int]): Int=    if (lst==Nil) 0 else lst.head+sum(lst.tail)

也可以使用模式匹配:

def su (lst: List[Int]): Int= lst match{    case Nil=>0    case h::t=>h+sum(t) //h是lst.head,t是lst.tail}

可变列表LinkedList

这里与C语言中的链表不太相同。我们可以对elem赋值来修改头部,对next赋值来修改尾部,与List相似。
注意:在List不是在给head和tail赋值。

val lst=scala.collection.mutable.LinkedList(1,-2,-4,9)lst.elem  //1lst.next //(-2,-4,9)lst.next.next  //(-4,9)var cur = lstwhile (cur!=Nil){    if(cur.elem<0) 0    cur=cur.next}

另一个例子,除去每两个元素中的一个

val lst=scala.collection.mutable.LinkedList(1,-2,-4,9)var cur = lstwhile(cur!=Nil && cur.next!=Nil){    cur.next=cur.next.next    cur=cur.next} //(1,-4

集(set)

无先后顺序、不重复的值的集合
尝试将已有的元素加入一个set是没有效果的。
集不保留元素插入的顺序,

val set1=scala.collection.mutable.Set(1,2,34,5) //(1,34,5,2)//如果允许集合自己对元素重新排列,查找元素的速度会快得多。所以在哈希集中查找元素比在数组或列表中快得多。val weekdays=scala.collection.mutable.LinkedHashSet("Mo","Tu","We","Th","Fr")  //使用LinkedHashSet可以记住元素被插入的顺序scala.collection.immutable.SortedSet(2,3,1,6,4) //已排序的集,(1,2,3,4,6)

注意:没有可变的已排序集。

一些方法与操作符

contains: 检查某个集是否包含给定的值
subsetOf:检查某个集当中的所有元素是否都被另一个集包含
union(++):可以理解为集合的并运算
diff(–): 可以理解为集合的差运算
+一般用于将元素添加到无先后次序的集合 (set)
:+,+: 一般用于将元素添加到有先后次序的集合的开头或结尾 (Vector,List,ArrayBuffer)
以上都不改变原有集合,而只是返回一个与原集合类型相同的新集合。

+=,-=,++=,–=,改值操作符,修改左侧操作元(所以左侧需要是变量)

映射

一组(键、值)对偶

map:将某个函数应用到集合中的每个元素并产出其结果的集合。
flatmap:如果这个函数的结果是产出一个集合而不是单一的值,仅使用map会得到一个集合包含着一些集合的结果。而使用flatmap会“消除”函数产出集合的作用,得到一个“平整的”原集合类型的集合。
collect:应用于偏函数(:只有部分输入被处理的函数),它产出被处理的所有参数的函数值的集合。"-3+4".collect{case '+'=>1;case '-' =>-1}// Vector(-1,1)
foreach:仅将函数应用到每个元素但不关心函数的值。names.foreach(println)

折叠方法

是二元函数,它处理集合中相邻的元素。

coll.reduceLeft(op):List(1,2,4,5).reduceLeft(_ + _)从集合第一个元素开始,将op相继应用到相邻元素。

coll.foldLeft(init)(op):List(1,2,4,5).foldLeft(0)(_ - _)从给定的init值开始,将op相继应用到集合的从左到右的元素。 或者协作 (init) /: coll (op) 如 ( 0 :/ List(1,2,4,5)(_ - _)

扫描方法

将折叠和映射操作结合在一起,得到包含有中间结果的集合。

(1 to 10).scanLeft(0)(_ + _) //Vector(0,1,3,6,10,15,21,28,...,55)

拉链操作

zip :将两个集合对应元素组合成一个个对偶的集合。

zipAll :可以指定较短列表的缺省值

List(1,2,3).zipAll(List(1,1),0,1) //0指当第一个集合较短时用0替代,1指当第二个集合较短时用1替代。List((1,1),(2,1),(3,1))

zipWithIndex: 返回对偶的列表。

"Scala".zipWithIndex //Vector(('S',0),('c',1),...('a',4))"Scala".zipWithIndex.max  //('l',3) 因为键l是最大的"Scala".zipWithIndex.max._1 // l"Scala".zipWithIndex.max._2   // 3

并行集合

scala可以自然的进行并行操作,多个线程可以并发的计算不同区块,在最后这些部分结果再被汇总到一起。
par方法进行并行操作

coll.par.sumcoll.par.count(_ % 2 ==0)

注意:par方法返回的秉性集合的类型为扩展自ParSeq,ParSet,ParMap特质的类,所有这些特质都是ParIterable的子类型,而不是Iterable的子类型。
可以用ser方法将并行集合转换为串行集合。

0 0