- 所有集合都扩展自Iterable特质。
- 集合有三大类,分别是序列,集,映射。
- 对于几乎所有集合类,scala都提供可变和不可变版本。
- scala列表要么是空的,要么拥有一头一尾,head,tail,tail本身又是一个列表。
- 集是无先后顺序的集合。
- 用LinkedHashSet来保留插入顺序,或者用SortedSet来按顺序进行迭代。
- +将元素添加到无先后顺序的集合中,+:,:+向前或者向后追加到序列。++将两个集合串接在一起,-,--移除元素
- 映射,折叠和拉链操作是很有用的技巧,用来将函数或操作应用到集合中的元素。
主要的集合特质
- Seq是一个由先后次序的值的序列,比如数组和列表。IndexedSeq允许我们随机访问数组元素。它是数组的超类型,但不是列表的超类型。
- Set是一组没有先后次序的值,SoredSet,元素以某种顺序被访问。
- Map是一组键值对,SortedMap按照键的顺序访问实体。 每个scala集合特质都有一个apply伴生对象,这个apply方法可以用来构建该集合的实例。
可变和不可变集合
不可变集合是线程安全,多线程可以安全共享其引用。scala会优先采用不可变集合。
import scala.collection.mutable
对不可变集合的每次修改都产生一个新的集合,而原来的集合并不改变。
def digits(n : Int) : Set[Int] = {
if(n < 0 )digits(-n)
else if (n < 10) Set(n)
else digits(n/10) + (n % 10)}
序列
Vector是ArrayBuffer的不可变版本,一个带下表的序列,支持快速的随机访问。向量是以树的形式实现的,每个节点可以有不超过32个子节点。
LinkedList
可变的LinkedList和不可变的List相似,只不过你可以通过对elem引用赋值来修改值,而对next引用赋值来修改其尾部。注意不是head和tail。
val lst = import scala.collection.mutable.LinkedList(1,-2,7,-9)
var cur = lst
while(cur != Nil){
if (cur.elem < 0) cur.elem = 0
cur = cur.next
}
集
val set1 = Set(1,2,3)
//元素无序
val set2= import scala.collection.mutable.LinkedHashSet(1,-2,7,-9)
//元素按照插入顺序排序
val set3= import scala.collection.immutable.SortedSet(1,-2,7,-9)
//元素按照已排序的顺序来访问集中的元素,红黑树
集提供两种方法contains subsetOf来检查某个集中的元素是否包含某个元素
val digits = Set(1,7,2,9)
digits contains 0 //false
Set(1,2) subsetOf digits //true
- union |,++
- intersect &
- diff &~,--
常用方法
- reduceLeft(op),reduceRight(op),foldLeft(init)(op),foldRight(init)(op)
- reduce(op),fold(init)(op) 以非特定顺序将二元操作符应用到所有元素,这里要求操作符是可以自由结合的----a(op)b op c =a op (b op c)
- sum,max,min
- map(f),flatMap(f),foreach(f)
- filter(pred),filterNot(pred)
- take(n),dorp(n),takeRight(n),dropRight(n) take返回前n个元素,drop则返回其他元素。
- zip()
- mkString(before,between,after) 构造一个由所有元素组成的字符串,可以提供三个参数。
- toArray,toSet,toMap
val names = List("Peter","Paul")
def ulcase(s : String) = Vector(s.toUpperCase(),s.toLowerCase())
names.map(ulcase)
//List(Vector("PETER","peter"),Vector("PAUL","paul"))
names.flatMap(ulcase)
//List("PETER","peter","PAUL","paul")
拉链操作zip
当你有两个集合需要结合在一起时,需要用到zip方法
val prices = List(5.0,20.0)
val quantities = List(10,2)
prices zip quantities
//List[(Double,Int)] = List((5.0,10),(20.0,2))
(prices zip quantities).map(p =>p._1 * p._2)
//注意元组的元素访问方法时._1
迭代器
val iter = coll.iterator
//使用iterator方法从集合获得一个迭代器
while(iter.hasNext)
iter.next()//操作
线程安全的集合
当你从多个线程访问一个可变集合时,你需要确保自己不会在其他线程正在访问它时对其修改,scala类库提供了6个特质,你可以将它们混入集合,这样在该集合的任何操作完成之前,其他线程才可能进行另外的操作。
- SynchronizedBuffer
- SynchronizedMap
- SynchronizedPriorityQueue
- SynchronizedQueue
- SynchronizedSet
- SynchronizedStack
val scores = new scala.collection.mutable.HashMap[String,Int] with
scala.collection.mutable.SynchronizedMap[String,Int]
并行集合
scala可以自动的将一些可以并行运算的算法并行实现。使用par方法。
coll.par.sum
//产生coll的一个并行实现,各个区块分别求和,最后汇总
for(i <- (0 to 10).par) println(i)
//可以看到数字是按照作用于该任务的线程顺序输出的,而不是0,1,,,10
注意,并不是所有的方法都可以并行化,比如reduceLeft等。
Comments !