scala的容器类

Seq的操作

特性(trait) Seq 具有两个子特征(subtrait) LinearSeqIndexedSeq。它们不添加任何新的操作,但都提供不同的性能特点:线性序列具有高效的 head 和 tail 操作,而索引序列具有高效的apply, length, 和 (如果可变) update操作。

Buffers是可变序列一个重要的种类。ListBuffer和ArrayBuffer是常用的buffer实现 。


集合:

集合是不包含重复元素的可迭代对象。

val fruit=Set("apple","orange","peach","banana")
fruit: scala.collection.immutable.Set[java.lang.String]=
Set(apple, orange, peach, banana)
scala> fruit("peach")
res0:Boolean=true
scala> fruit("potato")
res1:Boolean=false

可变集合操作:

有序集(SortedSet)
SortedSet 是指以特定的顺序(这一顺序可以在创建集合之初自由的选定)排列其元素(使用iterator或foreach)的集合。 

位集合(Bitset)
位集合是由单字或多字的紧凑位实现的非负整数的集合。


映射
映射(Map)是一种可迭代的键值对结构(也称映射或关联)。允许使用另一种语法:key -> value,来代替(key, value)。如:Map("x" -> 24, "y" -> 25, "z" -> 26)等同于Map(("x", 24), ("y", 25), ("z", 26)),却更易于阅读。

getOrElseUpdate特别适合用于访问用作缓存的映射(Map)

同步集合(Set)和映射(Map)
无论什么样的Map实现,只需混入SychronizedMap trait,就可以得到对应的线程安全版的Map。

import scala.collection.mutable.{Map,
SynchronizedMap,HashMap}
objectMapMaker{
def makeMap:Map[String,String]={
newHashMap[String,String]with
SynchronizedMap[String,String]{
overridedefdefault(key:String)=
"Why do you want to know?"
}
}
}


makeMap方法返回的可变映射混入了 SynchronizedMap trait,因此可以用在多线程环境下。对该映射的每次访问都是同步的。


具体的不可变集实体类:

List(列表)
列表List是一种有限的不可变序列式

两种构造方式:

// List of Integers
val nums: List[Int] = List(1, 2, 3, 4)
// List of Integers
val nums = 1 :: (2 :: (3 :: (4 :: Nil)))
可以使用:::运算符或列表List.:::()方法或List.concat()方法来添加两个或多个列表


Stream(流)
流Stream与List很相似,只不过其中的每一个元素都经过了一些简单的计算处理。也正是因为如此,stream结构可以无限长。

斐波那契数列的定义是,序列中的每个元素等于序列中在它之前的两个元素之和。

   
   
  1. scala> def fibFrom(a: Int, b: Int): Stream[Int] = a #:: fibFrom(b, a + b)
  2. fibFrom: (a: Int,b: Int)Stream[Int]
这段程序最大的亮点是在对序列进行计算的时候避免了无限递归。如果函数中使用 :: 来替换 #:: ,那么之后的每次调用都会产生另一次新的调用,从而导致无限递归。
scala> val fibs = fibFrom(1,1).take(7)
fibs: scala.collection.immutable.Stream[Int]=Stream(1,?)
scala> fibs.toList
res9:List[Int]=List(1,1,2,3,5,8,13)

Vector向量
用来解决List不能高效的进行随机访问的一种结构。
scala> val vec = scala.collection.immutable.Vector.empty
vec: scala.collection.immutable.Vector[Nothing] = Vector()
scala> val vec2 = vec :+ 1 :+ 2
vec2: scala.collection.immutable.Vector[Int] = Vector(1, 2)
Vector的元素不可更改,但可用update 新生成。

Immutable stacks(不可变栈

Immutable Queues(不可变队列)

Ranges (等差数列)
scala> 5 to 14 by 3
res3: scala.collection.immutable.Range = Range(5, 8, 11, 14)
scala> 1 until 3
res2: scala.collection.immutable.Range = Range(1, 2)



Immutable BitSets(不可变位集合)
BitSet代表一个由小整数构成的容器,这些小整数的值表示了一个大整数被置1的各个位。比如说,一个包含3、2和0的bit集合可以用来表示二进制数1101和十进制数13.

具有不可变的容器类:
Array Buffers
一个ArrayBuffer缓冲包含数组和数组的大小。另外,数组缓冲可以进行高效的尾插数据。

List Buffers
ListBuffer 类似于数组缓冲。区别在于前者内部实现是链表, 而非数组。如果你想把构造完的缓冲转换为列表,那就用列表缓冲,别用数组缓冲

StringBuilders
数组缓冲用来构建数组,列表缓冲用来创建列表。类似地,StringBuilder 用来构造字符串。

队列
Scala除了提供了不可变队列之外,还提供了可变队列。你可以像使用一个不可变队列一样地使用一个可变队列,但你需要使用+= 和++=操作符进行添加的方式来替代排队方法。

哈希表
Hash Table 用一个底层数组来存储元素,每个数据项在数组中的存储位置由这个数据项的Hash Code 来决定。
所以在Scala中默认的可变map和set都是基于Hash Table的。你也可以直接用mutable.HashSet 和 mutable.HashMap 来访问它们。

数组:
1、与Java的数组一致
2、是范型,可以创建Array[T]。
3、与Seq兼容,可以用Seq的任何方法。
总结,泛型数组创建需要类声明。所以每当创建一个类型参数T的数组,你还需要提供一个T的隐式类声明。最简单的方法是声明类型参数与ClassManifest的上下文绑定,如 [T: ClassManifest]。

性能特点:
http://docs.scala-lang.org/zh-cn/overviews/collections/performance-characteristics

视图:
总之,视图是协调性能和模块化的一个强大工具。但为了不被延迟利弊评估方面的纠缠,应该在2个方面对视图进行约束。要么你将在容器转换器不产生副作用的纯粹的功能代码里使用视图。要么你将它们应用在所有的修改都是明确的可变容器。最好的规避就是混合视图和操作,创建新的根接口,同时消除片面影响。

迭代器:
迭代器不是一个容器,更确切的说是逐一访问容器内元素的方法。迭代器it的两个基本操作是next和hasNext。调用it.next()会返回迭代器的下一个元素,并且更新迭代器的状态。在同一个迭代器上再次调用next,会产生一个新元素来覆盖之前返回的元素。如果没有元素可返回,调用next方法会抛出一个NoSuchElementException异常。
在迭代器或traversable容器中调用foreach方法的最大区别是:当在迭代器中完成调用foreach方法后会将迭代器保留在最后一个元素的位置。所以在这个迭代器上再次调用next方法时会抛出NoSuchElementException异常。与此不同的是,当在容器中调用foreach方法后,容器中的元素数量不会变化
scala> val it = Iterator("a", "number", "of", "words")
it: Iterator[java.lang.String] = non-empty iterator
scala> it.map(_.length)
res1: Iterator[Int] = non-empty iterator
scala> res1 foreach println
1
6
2
5
scala> it.next()
java.util.NoSuchElementException: next on empty iterator



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值