Scala集合

  • 所有集合都扩展自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 !