scala-collection

Scala的集合類可以從三個維度進(jìn)行切分:

可變與不可變集合(Immutable and mutable collections)

靜態(tài)與延遲加載集合 (Eager and delayed evaluation )

串行與并行計算集合(Sequential and parallel evaluation )

transformation,集合中有大量的操作都是把一個集合“轉(zhuǎn)換”成另一個集合,比如map,filter等等缸托。而Eager和Delayed集合的區(qū)別在于:Eager集合總是立即為元素分配內(nèi)存左敌,當(dāng)遇到一個transform動作時,Eager的集合會直接計算并返回結(jié)果俐镐,而Delayed集合則會盡可能晚的推遲執(zhí)行矫限,直到必須返回結(jié)果時才去執(zhí)行。這一點(diǎn)和Spark RDD操作中的transformation和action非常類似佩抹。

在現(xiàn)有的集合里叼风,只有Stream是Lasy的,所有其他的集合都是靜態(tài)(Eager)加載的匹摇。但是你可以很容易地把一個靜態(tài)集合轉(zhuǎn)換成lazy的咬扇,那就是創(chuàng)建一個view

集合類型總覽

Immutable?Collection

Immutable Seq

Seq主要分兩大類:indexed sequences和linear sequences,indexed sequences暗示本類集合在隨機(jī)讀取方面有較高的性能(類似數(shù)據(jù)結(jié)構(gòu)中的數(shù)組)廊勃。linear sequences暗示本類集合在head和tail操作和順序遍歷上更有優(yōu)勢(類似于數(shù)據(jù)結(jié)構(gòu)中的雙向列表

在使用Seq時,默認(rèn)使用的具體類是List, 使用IndexedSeq時默認(rèn)使用的具體類是Vector.

scala> val seq = Seq(1,2,3)seq: Seq[Int]= List(1,2,3)scala> val indexedSeq = IndexedSeq(1,2,3)indexedSeq: IndexedSeq[Int]= Vector(1,2,3)

Immutable Set

Immutable Map

Mutable Seq

如何選擇集合類

各種Immutable Sequence的特性比較

各種Mutable Sequence的特性比較

各種Map的特性比較

各種Set的特性比較


一经窖、常用操作符(操作符其實(shí)也是函數(shù))

++ ++[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) ?6?0 B): B 與foldRight等價

val left = List(1,2,3)

val right = List(4,5,6)

//以下操作等價

left ++ right? // List(1,2,3,4,5,6)

left ++: right? // List(1,2,3,4,5,6)

right.++:(left)? ? // List(1,2,3,4,5,6)

right.:::(left)? // List(1,2,3,4,5,6)

//以下操作等價

0 +: left? ? //List(0,1,2,3)

left.+:(0)? //List(0,1,2,3)

//以下操作等價

left :+ 4? ? //List(1,2,3,4)

left.:+(4)? //List(1,2,3,4)

//以下操作等價

0 :: left? ? ? //List(0,1,2,3)

left.::(0)? ? //List(0,1,2,3)

任何以冒號結(jié)果的操作符坡垫,都是右綁定的,即 0 :: List(1,2,3) = List(1,2,3).::(0) = List(0,1,2,3) 從這里可以看出操作::其實(shí)是右邊List的操作符画侣,而非左邊Int類型的操作符


5.util包

5.1.架構(gòu)

http://www.scala-lang.org/docu/files/collections-api/collections.html

The following figure shows all collections in packagescala.collection. These are all high-level abstract classes or traits, which generally have mutable as well as immutable implementations.

The main trait isIterable,which is the supertrait of both mutable and immutable variations of sequences (Seqs), sets, and maps. Sequences are ordered collections, such as arrays and lists. Sets contain at most one of each object, as determined by the==method. Maps contain acollectionof keys mapped to values.

Sequences, classes that inherit from traitSeq,let you work with groups of data lined up in order. Because the elements are ordered, you can ask for the first element, second element, 103rd element, and so on.

scala.collection.immutable

The immutability helps you develop correct, efficient algorithms because you never need to make copies of acollection.

scala.collection.mutable

不可變(collection.immutable._)

可變(collection.mutable._)

Array

ArrayBuffer

List

ListBuffer

String

StringBuilder

/

LinkedList, DoubleLinkedList

List

MutableList

/

Queue

Array

ArraySeq

Stack

Stack

HashMap HashSet

HashMap HashSet

ArrayStack

5.2.集合Array,List,Tuple

Array

長度固定

元素可變

確定長度冰悠,后賦值;

List

長度固定

元素不可變

Tuple

長度固定

元素不可變

常用于有多個返回值的函數(shù);或者多個變量的同時定義

Scala2.8中配乱,3者的元素都可以混合不同的類型(轉(zhuǎn)化為Any類型)溉卓;

Scala2.7中,Array搬泥、List都不能混合類型桑寨,只有Tuple可以;

Arraysallow you to hold a sequence of elements and efficiently access an element at an arbitrary position,both to get or update the element, with a zero-based index.

Listssupport fast addition and removal of items to the beginning of the list, but theydo notprovidefast accessto arbitrary indexes because theimplementation must iterate through the list linearly.

5.2.1.定義和初始化

5.2.1.1Array

val list1 = new Array[String](0) // Array()

val list2 = new Array[String](3) // Array(null, null, null)

val list3:Array[String] = new Array(3) // // Array(null, null, null)

val list1 = Array("a","b","c","d") //相當(dāng)于Array.apply("a","b","c","d")

定義一個類型為Any的Array:

val aa = Array[Any](1, 2)

或:

val aa: Array[Any] = Array(1, 2)

或:

val aa: Array[_] = Array(1, 2)

定義:

Array (1,3,5,7,9,11)

也可以用

Array[Int](1 to 11 by 2:_*)

暫時還沒有找到Range(例如 1 to 11 by 2)之后跟:_*的依據(jù)

Array對應(yīng)的可變ArrayBuffer:

val ab =collection.mutable.ArrayBuffer[Int]()

ab += (1,3,5,7)

ab ++= List(9,11) // ArrayBuffer(1, 3, 5, 7, 9, 11)

ab toArray // Array (1, 3, 5, 7, 9, 11)

ab clear // ArrayBuffer()

5.2.1.2List

val list:List[Int]= List(1,3,4,5,6) //或者List(1 to 6:_*)

val list1 = List("a","b","c","d") //或者List('a' to 'd':_*) map (_.toString)

元素合并進(jìn)List用::

val list2 = "a"::"b"::"c"::Nil // Nil是必須的

val list3 = "begin" :: list2 // list2不變忿檩,只能加在頭尉尾,不能加在尾

多個List合并用++,也可以用:::(不如++)

val list4 = list2++"end"++Nil

val list4 = list2:::"end" :: Nil //相當(dāng)于list2 ::: List("end")

當(dāng)import java.util._之后會產(chǎn)生沖突燥透,需要指明包

scala.List(1,2,3)

List對應(yīng)的可變ListBuffer:

val lb =scala.collection.mutable.ListBuffer(1,2,3)

lb.append(4) // ListBuffer(1, 2, 3, 4)

val lb =collection.mutable.ListBuffer[Int]()

lb += (1,3,5,7)

lb ++= List(9,11) // ListBuffer(1, 3, 5, 7, 9, 11)

lb.toList // List(1, 3, 5, 7, 9, 11)

lb.clear // ListBuffer()

建議定義方式:

val head::body = List(4,"a","b","c","d")

// head: Any = 4

// body: List[Any] = List(a, b, c, d)

val a::b::c = List(1,2,3)

// a: Int = 1

// b: Int = 2

// c: List[Int] = List(3)

定義固定長度的List:

List.fill(10)(2)// List(2, 2, 2, 2, 2, 2, 2, 2, 2, 2)

Array.fill(10)(2)// Array(2, 2, 2, 2, 2, 2, 2, 2, 2, 2)

又如:

List.fill(10)(scala.util.Random.nextPrintableChar)

// List(?, =, ^, L, p, <, \, 4, 0, !)

List.fill(10)(scala.util.Random.nextInt(101))

// List(80, 45, 26, 75, 24, 72, 96, 88, 86, 15)

5.2.1.3Tuple

val t1 = ("a","b","c")

var t2 = ("a", 123, 3.14, new Date())

val (a,b,c) = (2,4,6)

最簡單的Tuple:

1->"hello world"

和下面的寫法是等價的:

(1, "hello world")

To access elements of a tuple, you can use method_1to access the first element,_2to access the second, and so on:

scala> val v = (1, "Nick", 43)

scala> v._1

res179: Int = 1

scala> v._2

res180: String = Nick

scala> v._3

res181: Int = 43

5.2.1.4Vector

Scala2.8為了提高list的隨機(jī)存取效率而引入的新集合類型(而list存取前部的元素快沙咏,越往后越慢)辨图。

val v = Vector.empty

val v2 = 0+:v:+10:+20 // Vector(0, 10, 20), Vector那一邊始終有":"

v2(1) // 10

v2updated(1,100) // Vector(0, 100, 20)

這個例子舉的不太好,scala.collection.immutable. Vector擴(kuò)展肢藐、updated之后是新生成的vector故河,原vector保持immutable。這點(diǎn)和List類似吆豹。

Seq的缺省實(shí)現(xiàn)是List:

Seq(1,2,3) // List(1, 2, 3)

IndexSeq的缺省實(shí)現(xiàn)是Vector:

IndexSeq(1,2,3) // Vector(1, 2, 3)

5.2.1.5Range

Range(0, 5) // (0,1,2,3,4)

等同于:

0 until 5

等同于:

0 to 4

兩個Range相加:

('0' to '9') ++ ('A' to 'Z') // (0,1,..,9,A,B,...,Z)

Range和序列轉(zhuǎn)換:

1 to 5 toList

相當(dāng)與:

List(1 to 5:_*)

或者:

Vector(1 to 5: _*) // Vector(1,2,3,4,5)

5.2.1.6Stack Queue (List類的sibling)

先進(jìn)后出的堆棧:

val s =collection.immutable.Stack()

You push an element onto a stack withpush, pop an element withpop, and peek at the top of the stack without removing it withtop/head.

val s2 = s.push(10,20,30) // Stack(30, 20, 10)

s2.head// 30

s2.pop.pop // Stack(10)

對應(yīng)的可變Stack:

val ms =collection.mutable.Stack()

ms.push(1,3,5).push(7) // Stack(7, 5, 3, 1)

ms.head // 7

ms.pop // 7, ms = Stack(5,3,1)

先進(jìn)先出的隊列:

val q =collection.immutable.Queue() //也可指定類型Queue[Int]()

//You can append an element to an immutable queue withenqueue:

val q2 = q.enqueue(0).enqueue(List(10,20,30)) // Queue(0, 10, 20, 30)

//To remove an element from the head of the queue, you usedequeue:

q2.dequeue._1 // 0

q2.dequeue._2 // Queue(10, 20, 30)

On immutable queues, thedequeuemethod returns a pair (aTuple2) consisting of the element at the head of the queue, and the rest of the queue with the head element removed.

val qHas123 = Queue(1,2,3)

scala>val(element,?has23)?=?qHas123.dequeueelement:?Int?=?1has23:scala.collection.immutable.Queue[Int]?=?Queue(2,3)

對應(yīng)的可變Queue:

You use a mutable queue similarly to how you use an immutable one, but instead ofenqueue, you use the+=and++=operators to append. Also, on a mutable queue, thedequeuemethod will just remove the head element from the queue and return it.

val mq =collection.mutable.Queue[Int]()

mq+=(1,3,5)

mq++=List(7,9) // Queue(1, 3, 5, 7, 9)

mq dequeue // 1, mq= Queue(3, 5, 7, 9)

mq clear // Queue()

If you need a first-in-first-out sequence, you can use aQueue.

If you need a last-in-first-out sequence, you can use aStack.

5.2.1.7Stream

Stream相當(dāng)于lazy List抑胎,避免在中間過程中生成不必要的集合。

定義生成:

val st = 1#::2#::3#::Stream.empty // Stream(1, ?)

例子:fib數(shù)列的Stream版本簡單易懂

def fib(a: Int, b: Int): Stream[Int] = a#::fib(b,? a+b)

valfibs = fib(1, 1).take(7).toList // List(1, 1, 2, 3, 5, 8, 13)

fib數(shù)列的前后項比值趨于黃金分割:

def fn(n:Int) = fib(1,1)(n)

1 to 10 map (n=> 1.0*fn(n)/fn(n+1)) // Vector(0.5, 0.666, ..., 0.618)

例子1:

Range(1,50000000).filter (_ % 13==0)(1) // 26,但很慢垢啼,需要大量內(nèi)存

Stream.range(1,50000000).filter(_%13==0)(1) // 26筷频,很快,只計算最終結(jié)果需要的內(nèi)容

注意:

第一個版本在filter后生成一個中間collection速勇,size=50000000/13;而后者不生成此中間collection晌砾,只計算到26即可。

例子2:

(1 to 100).map(i=> i*3+7).filter(i=> (i%10)==0).sum // map和filter生成兩個中間collection

(1 to 100).toStream.map(i=> i*3+7).filter(i=> (i%10)==0).sum

5.2.2.使用(map, flatMap, filter, exists等)

5.2.2.1map

//類型可以混合:

import java.util._

val list3 = Array("a", 123, 3.14, new Date())

List("a","b","c").map(s=>s.toUpperCase()) //方式1

List("a","b","c").map(_.toUpperCase()) ????//方式2,類似于Groovy的it

// = List(A, B, C)

5.2.2.2filter filterNot

List(1,2,3,4,5).filter(_%2==0) // List(2, 4)

也可以寫成:

for (x<-List(1,2,3,4,5) if x%2==0) yield x

List(1,2,3,4,5).filterNot(_%2==0) // List(1, 3, 5)

5.2.2.3partition span splitAt groupBy

注:val (a,b) = List(1,2,3,4,5).partition(_%2==0) // (List(2,4), List(1,3,5))

可把Collection分成:滿足條件的一組烦磁,其他的另一組养匈。

和partition相似的是span,但有不同:

List(1,9,2,4,5).span(_<3)// (List(1),List(9, 2, 4, 5))都伪,碰到不符合就結(jié)束

List(1,9,2,4,5).partition(_<3)// (List(1, 2),List(9, 4, 5))呕乎,掃描所有

List(1,3,5,7,9)splitAt2// (List(1, 3),List(5, 7, 9))

List(1,3,5,7,9)groupBy(5<)// Map((true,List(7, 9)), (false,List(1, 3, 5)))

5.2.2.4foreach

打印:

Array("a","b","c","d").foreach(printf("[%s].",_))

// [a].[b].[c].[d].

5.2.2.5exists

//集合中是否存在符合條件的元素

List(1,2,3,4,5).exists(_%3==0) // true

5.2.2.6find

返回序列中符合條件的第一個陨晶。

例子:查找整數(shù)的第一個因子(最小因子猬仁、質(zhì)數(shù))

def fac1(n:Int) = if (n>= -1 && n<=1) n else (2 to n.abs) find (n%_==0) get

5.2.2.7sorted sortWith sortBy

例子(排序):

List(1,3,2,0,5,9,7).sorted//List(0, 1, 2, 3, 5, 7, 9)

List(1,3,2,0,5,9,7).sortWith(_>_)// List(9, 7, 5, 3, 2, 1, 0)

List("abc", "cb", "defe", "z").sortBy(_.size) //List(z, cb, abc, defe)

List((1,'c'), (1,'b'), (2,'a')).sortBy(_._2)// List((2,a), (1,b), (1,c))

5.2.2.8distinct

例子:(去除List中的重復(fù)元素)

def uniq[T](l:List[T]) = l.distinct

uniq(List(1,2,3,2,1)) // List(1,2,3)

5.2.2.9flatMap

flatMap的作用:把多層次的數(shù)據(jù)結(jié)構(gòu)“平面化”,并去除空元素(如None)先誉。

可用于:得到xml等樹形結(jié)構(gòu)的所有節(jié)點(diǎn)名稱湿刽,去除None等

例子1a:(兩個List做乘法)

List(1,2,3) * List(10,20,30) = List(10, 20, 30,20, 40, 60,30, 60, 90)

val (a,b) = (List(1,2,3), List(10,20,30))

aflatMap(i=> b map (j=> i*j))

等同于:

for (i<-a; i<-b) yield i*j //這個寫法更清晰

例子1b:

如果不用flatMap而是用map,結(jié)果就是:

amap(i=> b map (j=> i*j))// List(List(10, 20, 30), List(20, 40, 60), List(30, 60, 90))

等同于:

for (i<-a) yield { for (j<-b) yield i*j } //不如上面的清晰

例子2:

List("abc","def") flatMap (_.toList) // List(a, b, c, d, e, f)

List("abc","def") map (_.toList) // List(List(a, b, c), List(d, e, f))

例子3:flatMap結(jié)合Option

def toint(s:String) =

try { Some(Integer.parseInt(s)) } catch { case e:Exception => None }

List("123", "12a", "45") flatMap toint // List(123, 45)

List("123", "12a", "45") map toint // List(Some(123), None, Some(45))

5.2.2.10indices褐耳,zipWithIndex, slice

得到indices:

val a = List(100,200,300)

aindices// (0,1,2)

azipWithIndex// ((100,0), (200,1), (300,2))

(a indices) zip a // ((0,100), (1,200), (2,300))

截取一部分,相當(dāng)于String的substring

List(100,200,300,400,500)slice(2,4) // (300,400),取l(2), l(3)

5.2.2.11take drop splitAt

List(1,3,5,7) take 2 // List(1,3)

List(1,3,5,7) drop 2 // List(5,7)

5.2.2.12count

滿足條件的元素數(shù)目:

例如1000內(nèi)質(zhì)數(shù)的個數(shù):

def prime(n:Int) = if (n<2) false else 2 to math.sqrt(n).toInt forall (n%_!=0)

1 to 1000countprime? // 168

5.2.2.13updated patch

對于immutable的數(shù)據(jù)結(jié)構(gòu)诈闺,使用updated返回一個新的copy:

val v1 = List(1,2,3,4)

v1.updated(3,10) // List(1, 2, 3,10), v1還是List(1, 2, 3,4)

對于可變的數(shù)據(jù)結(jié)構(gòu),直接更改:

val mseq =scala.collection.mutable.ArraySeq(1, 2, 4,6)

mseq(3) = 10 // mseq = ArraySeq(1, 2, 4,10)

批量替換铃芦,返回新的copy:

val v1 = List(1,2,3,4,5)

val v2 = List(10,20,30)

v1 patch (0, v2, 3) // List(10,20,30,4,5),但v1,v2不變

5.2.2.14reverse reverseMap

1 to 5reverse// Range(5, 4, 3, 2, 1)

"james".reverse.reverse // "james"

reverseMap就是revese + map

1 to 5reverseMap(10*) // Vector(50, 40, 30, 20, 10)

相當(dāng)于:

(1 to 5 reverse) map (10*)

5.2.2.15contains startsWith endWith

1 to 5contains3 // true,后一個參數(shù)是1個元素

1 to 5containsSlice(2 to 4) // true,后一個參數(shù)是1個集合

(1 to 5)startsWith(1 to 3) // true后一個參數(shù)是1個集合

(1 to 5)endsWith(4 to 5)

(List(1,2,3)correspondsList(4,5,6)) (_<_)// true雅镊,長度相同且每個對應(yīng)項符合判斷條件

5.2.2.16集合運(yùn)算

List(1,2,3,4)intersectList(4,3,6) //交集= List(3, 4)

List(1,2,3,4)diffList(4,3,6) // A-B = List(1, 2)

List(1,2,3,4)unionList(4,3,6) // A+B = List(1, 2, 3, 4, 4, 3, 6)

//相當(dāng)于

List(1,2,3,4)++List(4,3,6) // A+B = List(1, 2, 3, 4, 4, 3, 6)

5.2.2.17殊途同歸

例子:得到(4, 16, 36, 64, 100)

寫法1:

(1 to 10)filter(_%2==0)map(x=>x*x)

寫法2:

for(x<-1 to 10ifx%2==0)yieldx*x

寫法3:

(1 to 10)collect{casexifx%2==0 => x*x }

5.2.2.18其他

對其他語言去重感興趣,可看看:

http://rosettacode.org/wiki/Remove_duplicate_elements

5.2.3.數(shù)組元素定位

統(tǒng)一使用()刃滓,而不是[]仁烹,()就是apply()的簡寫,a(i)===a.apply(i)

// Array

val a = Array(100,200,300) // a(0)=100, a(1)=200, a(3)=300

a(0) // 100,相當(dāng)于a.apply(0)

a(0)=10 // Array(10, 200, 300)注盈,相當(dāng)于a.update(0, 10)

// List

val list = List("a","b","c")

// list(0)=="a", list(1)=="b", list(2)=="c"

由于List不是index sequence晃危,定位訪問成本高,不建議使用。同樣不建議使用的還有List 的 length

// Tuple

val t1 = ("a","b","c") // t1._1="a", t1._2="b", t1._3="c"

5.2.4.view

在某類型的集合對象上調(diào)用view方法僚饭,得到相同類型的集合震叮,但所有的transform函數(shù)都是lazy的,從該view返回調(diào)用force方法鳍鸵。

對比:

val v = Vector(1 to 10:_*)

v map (1+) map (2*) //Vector(4,?6,?8,?10,?12,?14,?16,?18,?20,?22)

以上過程得生成2個新的Vector苇瓣,而:

val v = Vector(1 to 10:_*)

v.view map (1+) map (2*) force

只在過程中生成1個新的Vector,相當(dāng)于:

v map (x=>2*(1+x))

又如:

((1 to 1000000000) view).take(3).force // Vector(1,2,3)

使用Stream:

Stream.range(1,1000000000).take(3).force // ?Stream(1, 2, 3)

5.2.5.和Java集合間的轉(zhuǎn)換(scalaj)

方案一:Java的List很容易通過List.toArray轉(zhuǎn)換到Array偿乖,和Scala中的Array是等價的击罪,可使用map、filter等贪薪。

方案二:使用第三方的scalaj擴(kuò)展包(需自行下載設(shè)置classpath)

例子1:

val a1 = new java.util.ArrayList[Int]

a1.add(100); a1.add(200); a1.add(300)

//自行轉(zhuǎn)換

val a2 = a1.toArray

a2 map (e=>e.asInstanceOf[Int]) map(2*) filter (300>)

//采用scalaj(http://github.com/scalaj/scalaj-collection)

import scalaj.collection.Imports._

val a3 = a1.asScala

//scala->java

List(1, 2, 3).asJava

Map(1 -> "a", 2 -> "b", 3 -> "c").asJava

Set(1, 2, 3).asJava

// scalaj還可以在java的collection上使用foreach (目前除foreach外媳禁,還不支持filter、map)

a1.foreach(println)

scalaj的簡易文檔如下:

//Java toScala

Java類型

轉(zhuǎn)換方法

java.lang.Comparable[A]

#asScala:scala.math.Ordered[A]

java.util.Comparator[A]

#asScala:scala.math.Ordering[A]

java.util.Enumeration[A]

#asScala:scala.collection.Iterator[A]

#foreach(A => Unit): Unit

java.util.Iterator[A]

#asScala:scala.collection.Iterator[A]

#foreach(A => Unit): Unit

java.lang.Iterable[A]

#asScala:scala.collection.Iterable[A]

#foreach(A => Unit): Unit

java.util.List[A]

#asScala:scala.collection.Seq[A]

#asScalaMutable:scala.collection.mutable.Seq[A]

java.util.Set[A]

#asScala:scala.collection.Set[A]

#asScalaMutable:scala.collection.mutable.Set[A]

java.util.Map[A, B]

#asScala:scala.collection.Map[A, B]

#asScalaMutable:scala.collection.mutable.Map[A, B]

#foreach(((A, B)) => Unit): Unit

java.util.Dictionary[A, B]

#asScala:scala.collection.mutable.Map[A, B]

#foreach(((A, B)) => Unit): Unit

//Scalato Java

Scala類型

轉(zhuǎn)換方法

scala.math.Ordered[A]

#asJava: java.util.Comparable[A]

scala.math.Ordering[A]

#asJava: java.util.Comparator[A]

scala.collection.Iterator[A]

#asJava: java.util.Iterator[A]

#asJavaEnumeration: java.util.Enumeration[A]

scala.collection.Iterable[A]

#asJava: java.lang.Iterable[A]

scala.collection.Seq[A]

#asJava: java.util.List[A]

scala.collection.mutable.Seq[A]

#asJava: java.util.List[A]

scala.collection.mutable.Buffer[A]

#asJava: java.util.List[A]

scala.collection.Set[A]

#asJava: java.util.Set[A]

scala.collection.mutable.Set[A]

#asJava: java.util.Set[A]

scala.collection.Map[A, B]

#asJava: java.util.Map[A, B]

scala.collection.mutable.Map[A, B]

#asJava: java.util.Map[A, B]

#asJavaDictionary: java.util.Dictionary[A, B]

5.3.Map

5.3.1.定義Map

var m = Map[Int, Int]()

var m = Map(1->100, 2->200)

或者

var m = Map((1,100), (2,200))

相加:

val m = Map(1->100, 2->200)++Map(3->300)//Map((1,100), (2,200), (3,300))

可以用zip()生成Map:

List(1,2,3).zip(List(100,200,300)).toMap// Map((1,100), (2,200), (3,300))

注解:zip有“拉拉鏈”的意思画切,就是把兩排鏈扣完全對應(yīng)扣合在一起竣稽,非常形象。

5.3.2.不可變Map(缺省)

l定義:

val m2 =Map()

val m3 =Map(1->100, 2->200, 3->300)

指定類型:

val m1:Map[Int,String]= Map(1->"a",2->"b")

注:如果import java.util._后發(fā)生沖突霍弹,可指明:scala.collection.immutable.Map

保持循序的Map可以使用:

collection.immutable.ListMap

l讀取元素:

// m3(1)=100, m3(2)=200, m3(3)=300

// m3.get(1)=Some(100), m3.get(3)=Some(300), m3.get(4)=None

val v = m3.get(4).getOrElse(-1) // -1

或者簡化成:

m3.getOrElse(4, -1) // -1

l增加毫别、刪除、更新:

Map本身不可改變典格,即使定義為var岛宦,update也是返回一個新的不可變Map:

var m4 = Map(1->100)

m4 += (2->200) // m4指向新的(1->100,2->200), (1->100)應(yīng)該被回收

另一種更新方式:

m4.updated(1,1000)

增加多個元素:

Map(1->100,2->200)+(3->300, 4->400) // Map((1,100), (2,200), (3,300), (4,400))

刪除元素:

Map(1->100,2->200,3->300)-(2,3) // Map((1,100))

Map(1->100,2->200,3->300)--List(2,3) // Map((1,100))

l合并Mpa:

Map(1->100,2->200)++Map(3->300) // Map((1,100), (2,200), (3,300))

5.3.3.可變Map

val map =scala.collection.mutable.Map[String, Any]()

map("k1")=100???? //增加元素,方法1

map += "k2"->"v2" //增加元素耍缴,方法2

// map("k2")=="v2", map.get("k2")==Some("v2"), map.get("k3")==None

有則取之砾肺,無則加之:

val mm =collection.mutable.Map(1->100,2->200,3->300)

mmgetOrElseUpdate(3,-1) // 300, mm不變

mmgetOrElseUpdate(4,-1) // 300, mm=Map((2,200),(4,-1), (1,100), (3,300))

刪除:

val mm =collection.mutable.Map(1->100,2->200,3->300)

mm-=1 // Map((2,200), (3,300))

mm-=(2,3) // Map()

mm+=(1->100,2->200,3->300) // Map((2,200), (1,100), (3,300))

mm--=List(1,2) // Map((3,300))

mmremove1 // Some(300), mm=Map()

mm+=(1->100,2->200,3->300)

mm.retain((x,y) => x>1) // mm = Map((2,200), (3,300))

mm.clearn// mm = Map()

改變value:

mmtransform((x,y)=> 0) // mm = Map((2,0), (1,0), (3,0))

mm transform ((x,y)=> x*10) // Map((2,20), (1,10), (3,30))

mm transform ((x,y)=> y+3) // Map((2,23), (1,13), (3,33))

5.3.4.Java的HashMap

使用Java的HashMap:

val m1:java.util.Map[Int, String] = new java.util.HashMap

5.3.5.讀取所有元素

上面說過,Map(1->100,2->200,3->300)和Map((1,100),(2,200),(3,300))的寫法是一樣的防嗡,可見Map中的每一個entry都是一個Tuple债沮,所以:

for(e<-map) println(e._1 + ": " + e._2)

或者

map.foreach(e=>println(e._1 + ": " + e._2))

或者(最好

for ((k,v)<-map) println(k + ": " + v)

也可以進(jìn)行filter、map操作:

mapfilter(e=>e._1>1)// Map((2,200), (3,300))

mapfilterKeys(_>1)// Map((2,200), (3,300))

map.map(e=>(e._1*10, e._2)) // Map(10->100,20->200,30->300)

mapmap(e=>e._2)// List(100, 200, 300)

相當(dāng)于:

map.values.toList

5.3.6.多值Map

結(jié)合Map和Tuple本鸣,很容易實(shí)現(xiàn)一個key對應(yīng)的value是組合值的數(shù)據(jù)結(jié)構(gòu):

val m = Map(1->("james",20), 2->("qh",30), 3->("qiu", 40))

m(2)._1 // "qh"

m(2)._2 // 30

for((k,(v1,v2))<- m ) printf("%d: (%s,%d)\n", k, v1, v2)

5.3.7.Common operations for maps

What it isWhat it does

valnums=Map("i"->1,"ii"->2)Creates an immutable map (nums.toStringreturnsMap(i->1,ii->2))

nums+("vi"->6)Adds an entry (returnsMap(i->1,ii->2,vi->6))

nums-"ii"Removes an entry (returnsMap(i->1))

nums++List("iii"->3,"v"->5)Adds multiple entries (returnsMap(i->1,ii->2,iii->3,v->5))

nums--List("i","ii")Removes multiple entries (returnsMap())

nums.sizeReturns the size of the map (returns2)

nums.contains("ii")Checks for inclusion (returnstrue)

nums("ii")Retrieves the value at a specified key (returns2)

nums.keysReturns the keys (returns anIteratorover the strings"i"and"ii")

nums.keySetReturns the keys as a set (returnsSet(i,ii))

nums.valuesReturns the values (returns anIteratorover the integers1and2)

nums.isEmptyIndicates whether the map is empty (returns false)

importscala.collection.mutableMakes the mutable collections easy to access

valwords=

mutable.Map.empty[String,Int]Creates an empty, mutable map

words+=("one"->1)Adds a map entry from"one"to1(words.toStringreturnsMap(one->1))

words-="one"Removes a map entry, if it exists (words.toStringreturnsMap())

words++=List("one"->1,

"two"->2,"three"->3)Adds multiple map entries (words.toStringreturnsMap(one->1,two->2,three->3))

words--=List("one","two")Removes multiple objects (words.toStringreturnsMap(three->3))

5.4.Set

注:BitSet(collection.immutable.BitSet)和Set類似,但操作更快

5.4.1.定義

var s = Set(1,2,3,4,5) //scala.collection.immutable.Set

var s2 = Set[Int]() //scala.collection.immutable.Set[Int]

//增加元素:

s2 += 1? // Set(1)

s2 += 3? // Set(1,3)

s2 += (2,4) // Set(1,3,2,4)

//刪除元素

Set(1,2,3) - 2 // Set(1,3)

Set(1,2,3) - (1,2) // Set(3)

Set(1,2,3).empty // Set()全部刪除

//判斷是否包含某元素

s(3) // true,集合中有元素3

s(0) // false,集合中沒有元素0

//合并

Set(1,2,3)++Set(2,3,4) // Set(1, 2, 3, 4)

Set(1,2,3)--Set(2,3,4) // Set(1)

5.4.2.邏輯運(yùn)算

運(yùn)算

例子

交集

Set(1,2,3)&Set(2,3,4) // Set(2,3)

Set(1,2,3)intersectSet(2,3,4)

并集

Set(1,2,3)|Set(2,3,4) // Set(1,2,3,4)

Set(1,2,3)unionSet(2,3,4) // Set(1,2,3,4)

差集

Set(1,2,3)&~Set(2,3,4) // Set(1)

Set(1,2,3)diffSet(2,3,4) // Set(1)

5.4.3.可變BitSet

val bs =collection.mutable.BitSet()

bs += (1,3,5) // BitSet(1, 5, 3)

bs ++= List(7,9) // BitSet(1, 9, 7, 5, 3)

bs.clear // BitSet()

5.4.4.Common operations for sets

What it isWhat it does

valnums=Set(1,2,3)Creates an immutable set (nums.toStringreturnsSet(1,2,3))

nums+5Adds an element (returnsSet(1,2,3,5))

nums-3Removes an element (returnsSet(1,2))

nums++List(5,6)Adds multiple elements (returnsSet(1,2,3,5,6))

nums--List(1,2)Removes multiple elements (returnsSet(3))

nums**Set(1,3,5,7)Takes the intersection of two sets (returnsSet(1,3))

nums.sizeReturns the size of the set (returns3)

nums.contains(3)Checks for inclusion (returnstrue)

importscala.collection.mutableMakes the mutable collections easy to access

valwords=

mutable.Set.empty[String]Creates an empty, mutable set (words.toStringreturnsSet())

words+="the"Adds an element (words.toStringreturnsSet(the))

words-="the"Removes an element, if it exists (words.toStringreturnsSet())

words++=List("do","re","mi")Adds multiple elements (words.toStringreturnsSet(do,re,mi))

words--=List("do","re")Removes multiple elements (words.toStringreturnsSet(mi))

words.clearRemoves all elements (words.toStringreturnsSet())

5.5.Iterator

Iterator不屬于集合類型硅蹦,只是逐個存取集合中元素的方法:

val it = Iterator(1,3,5,7) // Iterator[Int] = non-empty iterator

it foreach println // 1 3 5 7

it foreach println //無輸出

三種常用的使用模式:

//1荣德、使用while

val it = Iterator(1,3,5,7) 或者 val it = List(1,3,5,7).iterator

while(it.hasNext) println(it.next)

// 2、使用for

for(e<- Iterator(1,3,5,7)) println(e)

//3童芹、使用foreach

Iterator(1,3,5,7)foreachprintln

Iterator也可以使用map的方法:

Iterator(1,3,5,7) map (10*) toList // List(10, 30, 50, 70)

Iterator(1,3,5,7) dropWhile (5>) toList // List(5,7)

由于Iterator用一次后就消失了涮瞻,如果要用兩次,需要toList或者使用duplicate:

val (a,b) = Iterator(1,3,5,7) duplicate // a = b = non-empty iterator

又如:

val it = Iterator(1,3,5,7)

val (a,b) = it duplicate

//在使用a假褪、b前署咽,不能使用it,否則a、b都不可用了宁否。

a toList // List(1,3,5,7)

b toList // List(1,3,5,7)

//此時it也不可用了

5.6.Paralllelcollection

Scala2.9+引入:

(1 to 10).parforeach println

多運(yùn)行幾次窒升,注意打印順序會有不同

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市慕匠,隨后出現(xiàn)的幾起案子饱须,更是在濱河造成了極大的恐慌,老刑警劉巖台谊,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蓉媳,死亡現(xiàn)場離奇詭異,居然都是意外死亡锅铅,警方通過查閱死者的電腦和手機(jī)酪呻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盐须,“玉大人玩荠,你說我怎么就攤上這事》岣瑁” “怎么了姨蟋?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長立帖。 經(jīng)常有香客問我眼溶,道長,這世上最難降的妖魔是什么晓勇? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任堂飞,我火速辦了婚禮,結(jié)果婚禮上绑咱,老公的妹妹穿的比我還像新娘绰筛。我一直安慰自己,他們只是感情好描融,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布铝噩。 她就那樣靜靜地躺著,像睡著了一般窿克。 火紅的嫁衣襯著肌膚如雪骏庸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天年叮,我揣著相機(jī)與錄音具被,去河邊找鬼。 笑死只损,一個胖子當(dāng)著我的面吹牛一姿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼叮叹,長吁一口氣:“原來是場噩夢啊……” “哼艾栋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起衬横,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤裹粤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蜂林,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遥诉,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年噪叙,在試婚紗的時候發(fā)現(xiàn)自己被綠了矮锈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡睁蕾,死狀恐怖苞笨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情子眶,我是刑警寧澤瀑凝,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站臭杰,受9級特大地震影響粤咪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渴杆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一寥枝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧磁奖,春花似錦囊拜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至身诺,卻和暖如春蔽莱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背戚长。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怠苔,地道東北人同廉。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親迫肖。 傳聞我的和親對象是個殘疾皇子锅劝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容