首页 > 学院 > 开发设计 > 正文

scala的容器类

2019-11-08 18:30:01
字体:
来源:转载
供稿:网友

Seq的操作

特性(trait) Seq 具有两个子特征(subtrait) LinearSeq和IndexedSeq。它们不添加任何新的操作,但都提供不同的性能特点:线性序列具有高效的 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=truescala> 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]withSynchronizedMap[String,String]{overridedefdefault(key:String)="Why do you want to know?"}}}

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

具体的不可变集实体类:

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

两种构造方式:

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

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

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

scala> def fibFrom(a: Int, b: Int): Stream[Int] = a #:: fibFrom(b, a + b)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.toListres9:List[Int]=List(1,1,2,3,5,8,13)Vector向量用来解决List不能高效的进行随机访问的一种结构。
scala> val vec = scala.collection.immutable.Vector.emptyvec: scala.collection.immutable.Vector[Nothing] = Vector()scala> val vec2 = vec :+ 1 :+ 2vec2: scala.collection.immutable.Vector[Int] = Vector(1, 2)Vector的元素不可更改,但可用update 新生成。Immutable stacks(不可变栈Immutable Queues(不可变队列)Ranges (等差数列)
scala> 5 to 14 by 3res3: scala.collection.immutable.Range = Range(5, 8, 11, 14)
scala> 1 until 3res2: scala.collection.immutable.Range = Range(1, 2)
Immutable BitSets(不可变位集合)BitSet代表一个由小整数构成的容器,这些小整数的值表示了一个大整数被置1的各个位。比如说,一个包含3、2和0的bit集合可以用来表示二进制数1101和十进制数13.具有不可变的容器类:Array Buffers一个ArrayBuffer缓冲包含数组和数组的大小。另外,数组缓冲可以进行高效的尾插数据。List BuffersListBuffer 类似于数组缓冲。区别在于前者内部实现是链表, 而非数组。如果你想把构造完的缓冲转换为列表,那就用列表缓冲,别用数组缓冲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 iteratorscala> it.map(_.length)res1: Iterator[Int] = non-empty iteratorscala> res1 foreach PRintln1625scala> it.next()java.util.NoSuchElementException: next on empty iterator
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表