官方collection教程
所有collection扩展自Iterable特质
三大类,序列,集合,映射 seq set map
对于几乎所有的collection,都提供了可变和不可变的版本
列表要么是空的,要么是一头一尾,尾是列表
集合没有先后次序
+ 将元素添加到无先后次序的容器中,+: 和 :+向前或向后追加到序列,++将两个集合串接到一起,-和–移除元素(1个减号和两个减号)
Iterable和Seq特质有数十个常见操作方法,很丰富
映射、折叠和拉链
主要的collection特质
下面请欣赏一组图片,注意蓝底白字(特质trait)和黑底白字(类class),虚线(隐式转换)和粗实线(默认实现)、细实线(通过类实现) 。图片来源 。
首先是scala.collection
scala.collection.immutable
scala.collection.mutable
图例
Iterable指的是那些能够交出用来访问集合中所有元素的Iterator的集合
val coll = List ( 2 , 1 , 4 , 3 )
val iter = coll. iterator
while ( iter. hasNext) {
println ( iter. next ( ) ) }
Seq是一个有先后次序的值的序列,例如数组或列表,IndexedSeq可以通过整型下标快速访问任意元素,ArrayBuffer带下标但链表不带。
Set是一组没有先后次序的值。
Map是一组键值的对偶。
每一个collection特质或类都带有一个apply方法的伴生对象,这个apply方法可以用来构建collection中的实例。
上面的三个图中出现的特质或类,统统可以直接拿来创建实例。图中粗实线是默认实现的关系,不管是Seq还是Iterable,默认的都是List
scala> Seq ( 1 , 2 , 3 )
res1: Seq[ Int] = List ( 1 , 2 , 3 )
scala> Iterable ( 1 , 2 , 3 )
res2: Iterable[ Int] = List ( 1 , 2 , 3 )
不同collection之间的转换,可以调用toXX方法,和to[C]的泛型方法
scala> val list = List ( 1 , 2 , 3 )
list: List[ Int] = List ( 1 , 2 , 3 )
scala> list. toVector
res5: Vector[ Int] = Vector ( 1 , 2 , 3 )
scala> list. to[ Vector]
res6: Vector[ Int] = Vector ( 1 , 2 , 3 )
使用==操作符实现任何seq、set、map的比较,如果不同类的collection比较,可以使用sameElements方法比较元素是否是相同。
scala> list == Vector ( 1 , 2 , 3 )
res8: Boolean = true
scala> list == Set ( 1 , 2 , 3 )
res9: Boolean = false
scala> list sameElements Set ( 1 , 2 , 3 , 2 )
res10: Boolean = true
可变和不可变的collection
不可变的collection可以安全共享引用,在多线程的应用程序中也无妨,scala.collection.Map, scala.collection.mutable.Map, scala.collection.immutable.Map,第一个是第二个和第三个的超类型
scala优先采用不可变集合,scala包和Predef对象里还有指向不可变特质的类型别名List、Set、Map。
使用可变的,import scala.collection.mutable,然后使用mutable.Map就是可变的了。
序列Seq
不可变的Seq
可变的Seq
对比上面两个图可以看出,不可变版的默认实现是Vector,可变版本的默认实现是ArrayBuffer。
Vector支持快速随机访问,是以树形结构的形式实现,每个节点可以有不超过32个子节点,速度很快
Range表示一个整数序列,只存储开始值、结束值、增值,可以使用to和until方法构造Range对象
此外还有栈、队列、优先级队列等
scala> Range ( 1 , 10 )
res16: scala. collection. immutable. Range = Range ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 )
scala> Range ( 1 , 10 , 2 )
res17: scala. collection. immutable. Range = Range ( 1 , 3 , 5 , 7 , 9 )
scala> 1 until 10
res18: scala. collection. immutable. Range = Range ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 )
scala> 1 to 10
res19: scala. collection. immutable. Range. Inclusive = Range ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 )
scala> val a = collection. mutable. Stack ( 1 , 2 , 3 )
a: scala. collection. mutable. Stack[ Int] = Stack ( 1 , 2 , 3 )
scala> a. push ( 10 )
res19: a. type = Stack ( 10 , 1 , 2 , 3 )
scala> a. pop
res20: Int = 10
scala> a
res21: scala. collection. mutable. Stack[ Int] = Stack ( 1 , 2 , 3 )
scala> val b = collection. mutable. Queue ( 1 , 2 , 3 , 4 )
b: scala. collection. mutable. Queue[ Int] = Queue ( 1 , 2 , 3 , 4 )
scala> b. enqueue ( 7 )
scala> b. dequeue
res23: Int = 1
列表
列表只有头和尾,head和tail,空列表Nil,head是第一个元素,tail是除了第一个元素以外的所有元素。
scala> val list = List ( 1 , 2 , 3 , 4 )
list: List[ Int] = List ( 1 , 2 , 3 , 4 )
scala> list. head
res24: Int = 1
scala> list. tail
res25: List[ Int] = List ( 2 , 3 , 4 )
scala> List ( 1 ) . tail
res26: List[ Int] = List ( )
从给定的head和tail创建新列表 使用::
操作符,这个操作符是右结合的,其右边需要是个List
scala> 100 : : list
res28: List[ Int] = List ( 100 , 1 , 2 , 3 , 4 )
scala> list : : 100
< console> : 13 : error: value : : is not a member of Int
list : : 100
scala> list : : list
res30: List[ Any] = List ( List ( 1 , 2 , 3 , 4 ) , 1 , 2 , 3 , 4 )
def sum ( lst: List[ Int] ) : Double= {
if ( lst == Nil) 0 else ( lst. head * 1.0 ) + sum ( lst. tail)
}
val a = ( 1 to 100000 ) . toList
def sum2 ( lst: List[ Int] ) : Int= lst match{
case Nil = > 0
case h : : t = > h+ sum2 ( t)
}
可别版本的List使用ListBuffer,链表支撑的数据结构,高效地从任意一端添加或移除元素,但是添加或移除元素并不高效。
集 Set
Set是不重复的元素的collection,默认顺序是hashcode方法进行组织,这样查找元素比在数组或列表中更快
scala> val s = Set ( 1 , 2 , 3 )
s: scala. collection. immutable. Set[ Int] = Set ( 1 , 2 , 3 )
scala> s+ 1
res34: scala. collection. immutable. Set[ Int] = Set ( 1 , 2 , 3 )
链式哈希set可以保留元素的插入顺序LinkedHashSet
scala> Set ( 1 to 5 : _* )
res8: scala. collection. immutable. Set[ Int] = Set ( 5 , 1 , 2 , 3 , 4 )
scala> for ( i < - Set ( 1 , 2 , 3 , 4 , 5 , 6 ) ) println ( i)
5
1
6
2
3
4
scala> val s1 = collection. mutable. LinkedHashSet ( 1 , 2 , 3 , 4 , 5 , 6 )
s1: scala. collection. mutable. LinkedHashSet[ Int] = Set ( 1 , 2 , 3 , 4 , 5 , 6 )
scala> for ( i < - s1) println ( i)
1
2
3
4
5
6
scala> collection. mutable. SortedSet ( 5 , 1 , 3 , 2 , 4 )
res11: scala. collection. mutable. SortedSet[ Int] = TreeSet ( 1 , 2 , 3 , 4 , 5 )
位组集合,BitSet,以一个字符序列的方式存放非负整数,只能是正的Int型的,不能太大,也不能是其他类型的。如果位组中有i,那么低i个字位是1。
scala> collection. immutable. BitSet ( 1 , 2 , 3 , 2 )
res35: scala. collection. immutable. BitSet = BitSet ( 1 , 2 , 3 )
scala> collection. immutable. BitSet ( 1 , 2 , 2100000000 )
java. lang. OutOfMemoryError: Java heap space
contains方法检查一个集合是不是包含某个元素,subsetOf方法检查某个集合是否被另一个集合包含
集合的运算,交集、并集、差集,符号太麻烦,还是记忆union intersect diff简单
操作
方法
符号1
符号2
并
union
|
++
交
intersect
&
差
diff
&~
--
scala> val s1 = Set ( 1 , 2 , 3 )
s1: scala. collection. immutable. Set[ Int] = Set ( 1 , 2 , 3 )
scala> val s2 = Set ( 2 , 3 , 4 )
s2: scala. collection. immutable. Set[ Int] = Set ( 2 , 3 , 4 )
scala> val s3 = Set ( 7 , 8 )
s3: scala. collection. immutable. Set[ Int] = Set ( 7 , 8 )
scala> s1. union ( s2)
res38: scala. collection. immutable. Set[ Int] = Set ( 1 , 2 , 3 , 4 )
scala> s1. intersect ( s2)
res39: scala. collection. immutable. Set[ Int] = Set ( 2