1. 程式人生 > >Scala集合(一)

Scala集合(一)

bsp def tree += 順序 == trees 特質 amp

Scala集合的主要特質

技術分享圖片

Iterator,用來訪問集合中所有元素

val coll = ... // 某種Iterable

val iter = col.iterator

while(iter.hasNext)

  iter.next()

Seq是一個有先後次序的值得序列,比如數組或列表。
IndexSeq允許我們通過整型的下標快速訪問任意元素,如ArrayBuffer是帶下標的。
Set是一組沒有先後次序的值,在SortedSet中,元素以某種排過序的順序被訪問。
Map是一組(K,V)對偶,SortedMap按照鍵的排序訪問。

每個Scala集合特質或類,都有一個帶有apply方法的伴生對象,這個apply方法可以用來構建該集合中的實例。

Iterable(
0xFF, 0xFF00, 0xFF0000) set(color.RED, color.GREEN, Color.BLUE) Map(color.RED -> -0xFF0000, Color.GREEN -> 0xFF00, Color.BLUE -> 0xFF) SortedSet("Hello" , "World")

可變和不可變集合

scala.collection.mutable.Map    //可變

scala.collection.immutable.Map //不可變 

scala.collection.Map //超類

Scala優先采用不可變集合, scala.collection 包中的伴生對象產出不可變的集合

scala.collection.Map(
"Hello" -> 42) //不可變映射 因為Scala包和Predef對象總是被引入,他們都指向不可變特質的類型別名List、Set和Map. Preedef.Map和scala.collection.immutable.Map是一回事 import scala.collection.mutable 用Map得到不可變,用mutable.Map得到可變的。

序列

技術分享圖片

Vector是ArrayBuffer的不可變版本,一個帶下標的序列,支持快捷的隨機訪問,以樹形結構的形式實現。

Range表示一個整數序列,只存儲起始值,結束值和增值, 用 to 和 until 方法來構造Range對象。

技術分享圖片

列表

列表要麽是Nil(空表),要麽是一個head元素和一個tail,tail又是一個列表。

val digits = List(4,2)

digits.head //4

digits.tail// List(2)

digits.tail.head// 2

digits.tail.tail //Nil

:: 操作符從給定的頭和尾創建一個新的列表。

9 :: List(4,2) // List(9,4,2)

9 :: 4 :: 2 :: Nil  // :: 是右結合,列表從末端開始構建

9 :: ( 4 :: (2 :: Nil ) )

叠代, 除了遍歷外,可以用 遞歸 模式匹配

def sum(lst : List[Int]): Int = 

  if( lst == Nil) 0 else lst.head + sum(lst.tail)

 

def sum(lst:List[Int]): Int = lst match{

  case Nil => 0

  case h :: t => h+sum(t) // h 是 lst.head, 而t是lst.tail, ::將列表“析構”成頭部和尾部

}

直接使用List的方法

List(9,4,2).sum

可變列表

LinkedList, elem指向當前值,next指向下一個元素

DoubleLinkedList多帶一個prev

val lst = scala.collection.mutable.LinkedList(1,-2,7,-9)

var cur = lst

while(cur != Nil){

  if(cur.elem<0) cur.elem = 0

  cur = cur.next

} // (1,0,7,0) ,將所有負值改為0

var cur = lst 

while(cur != Nil && cur.next != Nil){

  cur.next = cur.next.next

  cur = cur.next

}// 去除每兩個元素中的一個

註:當要把某個節點變為列表中的最後一個節點,不能將next 設為Nil 或 null, 而將它設為LinkedList.empty。

不重復元素的集合,以哈希集實現,元素根據hashCode方法的值進行組織

Set(2,0,1) + 1 // (2,0,1)


LinkedHashSet,鏈式哈希集 記住元素被插入的順序

val weekdays = scala.collection.mutable.LinkedHashSet(1,2,3,4)


排序的集

scala.collection.immutable.SortedSet(1,2,3,4) // 用紅黑樹實現的

Scala 2.9沒有可變的已排序集,用java.util.TreeSet


位集(bit set), 以一個字位序列的方式存放非負整數,如果集中有i,則第i個字位是1

高效的實現,只要最大元素不是特別大。

Scala提供 可變和不可變的兩個 BitSet類


contains 檢查是否包含, subsetOf 檢查集的所有元素是否被另一個集包含

val digits = Set(1,7,2,9)

digits contains 0 // false

Set(1,2) subsetOf digits // true
union intersect diff 方法,也可寫作| ,&, &~

union 還可以寫成 ++, diff 寫作 --

val primes = Set(2, 3, 5, 7)

digits union primes // Set(1,2,3,5,7,9)

digits & primes // Set (2,7)

digits -- primes // Set(1,9)

技術分享圖片

一般而言,+用於將元素添加到無先後次序的集合,而+:和:+則是將元素添加到有先後次序的集合的開頭或末尾。

Vector(1,2,3) :+ 5 //Vector(1,2,3,5)

1 +: Vector(1,2,3) //Vector(1,1,2,3) 

以冒號結尾的操作符,+:是右結合的,這些操作符都返回新的集合


可變集合有 +=操作符 用於修改左側操作元

val numbers = ArrayBuffer(1,2,3)

numbers += 5 // 將 5 添加到 numbers


不可變集合,可以在var上使用+=或:+=

var numbers = Set(1,2,3)

numbers += 5 // numbers 設為不可變的集numbers + 5

var numberVector = Vector(1,2,3)

numbersVector :+= 5 // 向量沒有+操作符,只有:+

 
移除元素

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


++來一次添加多個元素, -- 一次移除多個元素

col1 ++ col2 

技術分享圖片

Scala集合(一)