Traversable 特质
SCALA集合类层级的顶端是 Traversable 特质。它只有一个抽象方法 foreach:
def foreach[U](f: Elem => U)
实现 Traversable 的集合类只需要定义这个方法;所有其他的方法都能直接从 Traversable 中继承下来。
foreach 方法用于遍历集合中的所有元素,并且对每个元素调用 f 函数。函数 f 的类型是 Elem=>U,其中 Elem 是集合中元素的类型,U是任意的函数返回值类型。这里对 f 的调用只是为了产生副作用,事实上任意 f 的调用返回值都被 foreach 直接抛弃。
Traversable 特质中定义了许多具体方法,如后面的表格中所示。这些方法可以分为如下类型:
- Addition类操作, ++方法, 用于将两个Traversable 的示例连接到一起,或者将一个Iterable实例的所有元素添加到一个 Traversable 实例;
- Map 类操作,map、flatMap 以及 collect 方法,用于对集合中每个元素应用一些函数从而产生一个新的集合;
- Conversions类操作,toArray、toList、toIterable、toSeq、toIndexedSeq、toStream、toSet 以及 toMap,用于将一个 Traversable 的实例转换为其具体的类型。如果集合的运行时类型与所要求转换的类型匹配,那么直接返回当前集合实例。例如,对一个 List 类的实例调用 toList 方法将返回这个实例本身;
- Copy 类操作,copyToBuffer 以及 copyToArray。就如同他们的名字所表达的意思,这两个方法分别将集合中的元素拷贝到一个Buffer或者一个Array;
- Size info类操作,isEmpty、nonEmpty、size 以及 hasDefiniteSize:Traversable 的集合实例可以是有限长度或者是无限长度的。一个自然数的集合 Stream.from(0) 就是无限长度的一个例子。hasDefiniteSize 方法指示一个集合是否可能是无限的。如果 hasDefiniteSize 方法返回 true,则该集合肯定是有限的;如果返回 false,则该集合还未得到充分的修饰(也即根据目前的情况无法判断),因此可能是无限长度也可能是有限长度的;
- Element retrieval 类操作,head、last、headOption、lastOption 以及 find。这些方法选择集合的第一个(最后一个)元素,或者满足给定谓词条件的第一个元素。值得注意的是并不是所有的集合都对 “first” 与 “last” 有一个明确的意义。例如,一个HashSet可能根据hash key来存储元素,存储的位置可能在不同运行过程中各不相同。在这种情况下,一个 Hash Set 的第一个元素同样也会在不同的运行过程中产生不同的值。如果一个集合总是能依照同样的次序来产生元素,那么这个集合称之为有序的。大多数集合类是有序的,但是也有一些集合(e.g. Hash Set)不是有序的--这些集合类为了获取一些额外的性能提升而去除了集合中元素的顺序。有序对于重现问题和定位问题都是非常重要的。因此,Scala 集合框架对所有的集合类型都提供了有序的版本。例如,HashSet 的有序版本是 LinkedHashSet;
- Sub-collection retrieval 类操作,tail、init、slice、take、drop、takeWhile、dropWhile、filter、filterNot 以及 withFilter。这些方法返回当前集合中指定索引范围内的一个子集或者是满足给定谓词条件的一个子集;
- Subdivision 类操作,splitAt、span、partition 以及 groupBy,这些方法将当前集合划分为几个子集;
- Element tests 类操作,exists、forall 以及 count,用于判断集合中元素是否满足给定谓词条件;
- Folds 类操作,foldLeft、foldRight、/:、:\、reduceLeft 以及 reduceRight,这些方法使用一个二元函数依次对集合中元素进行迭代操作;
- Specific folds 类操作,sum、product、min 以及 max,他们只对一些特定类型启作用(numeric 或者 comparable);
- String 类操作,mkString、addString 以及 stringPrefix,这些方法为从集合转化为字符串提供一个另外一种选择;
- View 类操作,包括两个被重写的 view 方法的变体。view 是一个延迟赋值的集合。后面的章节中,你会学习到更多关于 view 的知识。
Traversable 中的方法
方法 | 作用 |
Abstract Method: | |
xs foreach f | 对xs中每个元素调用函数 f |
Addition: | |
xs ++ ys | 一个包含 xs 和 ys 中所有元素的新的集合。 ys 是一个 TraversableOnce 类的集合实例, i.e. 一个 Traversable 类实例或者一个 Iterator 类实例。 |
Maps: | |
xs map f | 将xs中每一个元素应用函数 f 得到的由 f 函数调用结果组成的一 个新的集合 |
xs flatMap f | 对 xs 中每一个元素(元素为集合实例)应用函数 f,最后将结果 集合合并成一个新的集合 |
xs collect f | 对 xs 中每一个元素调用偏函数 f,并将 f 中有定义的集合元素的 函数调用结果组成一个新的集合 |
Conversions: | |
xs.toArray | 将集合转化为一个数组 |
xs.toList | 将集合转化为一个 Lis t实例 |
xs.toIterable | 将集合转化为一个 Iterable 类实例 |
xs.toSeq | 将集合转化为一个 Seq 类实例 |
xs.toIndexedSeq | 将集合转化为一个 IndexedSeq 类实例 |
xs.toStream | 将集合转化为一个延迟计算的流 |
xs.toSet | 将集合转化为一个Set类实例 |
xs.toMap | 将一个(key, value)对的集合转化为一个Map类实例。 如果当前集合的元素类型不是(key, value)对形式, 则报静态类型错误 |
Copying: | |
xs copyToBuffer buf | 拷贝集合中所有元素到缓存 buf |
xs copyToArray(arr,s,n) | 拷贝最多n个集合中的元素到数组中从索引 s 开始的序列中。 最后两个参数是可选的。 |
Size info: | |
xs.isEmpty | 判断集合是否为空 |
xs.nonEmpty | 判断集合是否包含元素 |
xs.size | 返回集合中元素的个数 |
xs.hasDefiniteSize | 判断 xs 是否一定是元素个数有限的 |
Element Retrieval: | |
xs.head | 返回集合中的第一个元素(如果无序,则返回一个不确定的元素) |
xs.headOption | 以Option类实例的方式返回集合中的第一个元素, 如果集合为空则返回None |
xs.last | 返回集合中的最后一个元素(如果无序,则返回一个不确定的元素) |
xs.lastOption | 以Option类实例的方式返回集合中的最后一个元素, 如果集合为空则返回None |
xs find p | 以Option类实例的方式返回满足谓词条件 p 的第一个元素, 如果都不满足则返回None |
Subcollection: | |
xs.tail | 除了第一个元素之外的其他元素组成的集合 |
xs.init | 除了最后一个元素之外的其他元素组成的集合 |
xs slice (from, to) | 返回给定索引范围之内的元素组成的集合 (从索引from到索引to,但不包含索引to指示的元素) |
xs take n | 返回xs的前n个元素组成的集合(如果无序,则返回任意n个元素) |
xs drop n | 返回xs的后n个元素组成的集合(如果无序,则返回任意n个元素) |
xs takeWhile p | 从第一个元素开始遍历查找满足谓词条件 p 的元素, 直到遇到一个不满足条件的元素,则返回所有目前 找到的元素 |
xs dropWhile p | 其实就是xs 与 xs takeWhile p 的差集 |
xs filter p | 返回满足给定谓词条件 p 的所有元素组成的集合 |
xs withFilter p | 该集合的一个非严格的过滤器。后续对方法 map、flatMap 以及 withFilter 的调用都只针对xs中满足谓词条件 p 的元素,而忽略 其他元素 |
xs filterNot p | 返回不满足给定谓词条件 p 的所有元素组成的集合 |
Subdivisions: | |
xs splitAt n | 在给定位置分裂集合,返回一个集合对 (xs take n, xs drop n) |
xs span p | 根据给定谓词集合分裂集合,返回一个集合对(xs takeWhile p, xs dropWhile p) |
xs partition p | 将 xs 分裂为两个集合;一个是由满足谓词条件 p 的元素组成的集合, 另一个是不满足谓词条件 p 的元素组成的集合 |
xs groupBy f | 根据给定的类别函数 f 将 xs 中的元素划分为不同的集合, 最后返回一个映射,其中key为 f 产生的类别值,value 为 xs 中产生该类别值的所有元素组成的集合。 |
Element Conditions: | |
xs forall p | 判断是否集合中所有的元素都满足谓词条件 p |
xs exists p | 判断是否集合中至少存在一个元素满足谓词条件 p |
xs count p | xs 中满足谓词条件 p 的元素的个数 |
Folds: | |
(z /: xs) (op) | 以 z 为初始值,从左到右对 xs 中的元素连续调用二元函数 op |
(xs :\ z) (op) | 以 z 为初始值,从右到左对 xs 中的元素连续调用二元函数 op |
xs.foldLeft(z) (op) | 同 (z /: xs) (op) |
xs.foldRight(z) (op) | 同 (xs :\ z) (op) |
xs reduceLeft op | 从左到右对非空集合 xs 中的元素连续调用二元函数 op |
xs reduceRight op | 从右到左对非空集合 xs 中的元素连续调用二元函数 op |
Specific Folds: | |
xs.sum | xs 中所有元素的数值和 |
xs.product | xs 中所有元素的数值积 |
xs.min | xs 中所有元素中的最小值(元素需要是可比的) |
xs.max | xs 中所有元素中的最大值(元素需要是可比的) |
String: | |
xs addString (b, start, sep, end) | 向 StringBuilder 类的实例 b 中添加一个字符串, 这个字符串显示了 xs 所有元素,具体格式是以 seq 字符串分隔元素,并将 start 字符串和 end 字符串添加到头和尾。其中,start、seq 和 end 都是可选的 |
xs mkString (start, seq, end) | 将集合转化为一个字符串, 这个字符串显示了 xs 所有元素,具体格式是以 seq 字符串分隔元素,并将 start 字符串和 end 字符串添加到头和尾。其中,start、seq 和 end 都是可选的 |
xs.stringPrefix | 返回集合的名字前缀,这个前缀是 xs.toString 的返回结果的开头 |
Views: | |
xs.view | 生成一个 xs 上的 view |
xs view (from, to) | 生成一个view 来表示 xs 上指定索引范围内的元素 |