Scala 2.8 集合设计教程
继我的困惑之后,有哪些好的资源可以解释新的Scala 2.8 集合库已经结构化。我有兴趣找到有关以下内容如何组合在一起的一些信息:
- 集合类/特征本身(例如
List
、Iterable
) - 为什么喜欢 类存在(例如
TraversableLike
) - 伴随方法的用途(例如
List.companion
) - 我如何知道哪些
隐式
对象在作用域内给定点
Following on from my breathless confusion, what are some good resources which explain how the new Scala 2.8 collections library has been structured. I'm interested to find some information on how the following fit together:
- The collection classes/traits themselves (e.g.
List
,Iterable
) - Why the Like classes exist (e.g.
TraversableLike
) - What the companion methods are for (e.g.
List.companion
) - How I know what
implicit
objects are in scope at a given point
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
前言
Martin Odersky 有一个 2.8 集合演练,可能应该是你的第一个参考。它还补充了架构注释 ,这对于那些想要设计自己的系列的人来说会特别感兴趣。
这个答案的其余部分是在任何此类东西存在之前写的(事实上,在 2.8.0 本身发布之前)。
您可以找到一篇关于它的论文 Scala SID #3。对于那些对 Scala 2.7 和 2.8 之间的差异感兴趣的人来说,该领域的其他论文也应该很有趣。
我将选择性地引用该论文,并补充我的一些想法。还有一些由 Matthias 在 decodified.com 生成的图像,原始 SVG 文件可以在 这里。
集合类/特征本身
集合的特征实际上分为三种层次结构:一种用于可变集合,一种用于不可变集合,一种不对集合做出任何假设。
并行、串行和可能并行集合之间也有区别,这是在 Scala 2.9 中引入的。我将在下一节中讨论它们。本节中描述的层次结构专门针对非并行集合。
下图显示了 Scala 2.8 引入的非特定层次结构:
显示的所有元素都是特征。在另外两个层次结构中,还有直接继承特征的类以及通过隐式转换为包装类可以被视为属于该层次结构的类。这些图表的图例可以在它们后面找到。
不可变层次结构图:
可变层次结构图:
图例:
这是集合层次结构的缩写 ASCII 描述,供那些看不到图像的人参考。
并行集合
当 Scala 2.9 引入并行集合时,设计目标之一是使其使用尽可能无缝。用最简单的术语来说,可以用并行集合替换非并行(串行)集合,并立即获得好处。
然而,由于在此之前所有集合都是串行的,因此许多使用它们的算法都假设并依赖于它们是串行的这一事实。提供给具有此类假设的方法的并行集合将会失败。因此,上一节中描述的所有层次结构都要求串行处理。
创建了两个新的层次结构来支持并行集合。
并行集合层次结构具有相同的特征名称,但前面带有
Par
:ParIterable
、ParSeq
、ParMap
和ParSet
。请注意,没有ParTraversable
,因为任何支持并行访问的集合都能够支持更强的ParIterable
特征。它也不具有串行层次结构中存在的一些更专门的特征。整个层次结构位于目录 scala.collection.parallel 下。实现并行集合的类也有所不同,
ParHashMap
和ParHashSet
用于可变和不可变并行集合,还有ParRange
和ParVector
code> 实现immutable.ParSeq
和ParArray
实现mutable.ParSeq
。还存在另一个层次结构,它反映了串行和并行集合的特征,但带有前缀
Gen
:GenTraversable
、GenIterable
、GenSeq< /code>、
GenMap
和GenSet
。这些特征是并行和串行集合的父。这意味着采用Seq
的方法无法接收并行集合,但采用GenSeq
的方法预计可以处理串行和并行集合。鉴于这些层次结构的构造方式,为 Scala 2.8 编写的代码与 Scala 2.9 完全兼容,并且需要串行行为。如果不重写,它就无法利用并行集合,但所需的更改非常小。
使用并行集合
任何集合都可以通过调用方法
par
转换为并行集合。同样,任何集合都可以通过调用方法seq
转换为串行集合。如果集合已经是所请求的类型(并行或串行),则不会发生任何转换。然而,如果对并行集合调用
seq
或对串行集合调用par
,则会生成具有所请求特征的新集合。不要混淆
seq
(将集合转换为非并行集合)和toSeq
(返回从集合的元素创建的Seq
)收藏。对并行集合调用toSeq
将返回ParSeq
,而不是串行集合。主要特征
虽然有许多实现类和子特征,但层次结构中有一些基本特征,每个特征都提供更多方法或更具体的保证,但减少了可以实现它们的类的数量。
在下面的小节中,我将简要描述主要特征及其背后的想法。
Trait TraversableOnce
此特征与下面描述的特征
Traversable
非常相似,但有一个限制,即您只能使用它一次。也就是说,在TraversableOnce
上调用的任何方法都可能导致其无法使用。此限制使得可以在集合和迭代器之间共享相同的方法。这使得使用
Iterator
但不使用特定于Iterator
的方法的方法实际上能够使用任何集合,加上迭代器(如果重写)接受TraversableOnce
。因为
TraversableOnce
统一了集合和迭代器,所以它不会出现在前面的图中,这些图中只涉及集合。Trait Traversable
位于集合层次结构顶部的是
Traversable
特征。它唯一的抽象操作是该操作旨在遍历集合的所有元素,并将给定的操作 f 应用于每个元素
元素。这样做只是为了它的副作用;事实上 f 的任何函数结果都会被丢弃
foreach。
可遍历的对象可以是有限的或无限的。无限可遍历对象的一个例子是流
自然数
Stream.from(0)
。方法hasDefiniteSize
指示集合是否可能无限。如果
hasDefiniteSize
返回 true,则该集合肯定是有限的。如果返回 false,则集合尚未完全阐述,因此它可能是无限的或有限的。
此类定义了可以通过
foreach
有效实现的方法(超过 40 个)。Trait Iterable
该特征声明了一个抽象方法
iterator
,它返回一个迭代器,该迭代器一一生成集合的所有元素。Iterable
中的foreach
方法是通过iterator
实现的。为了提高效率,Iterable
的子类通常使用直接实现来重写 foreach。Iterable
类还为Traversable
添加了一些不常用的方法,只有在iterator
可用的情况下才能有效实现。它们总结如下。其他特征
在
Iterable
之后,有三个继承自它的基本特征:Seq
、Set
和Map
。这三个都有一个 apply 方法,并且三个都实现了 PartialFunction 特征,但是 apply 的含义在每种情况下都不同。我相信
Seq
、Set
和Map
的含义很直观。在它们之后,这些类分解为特定的实现,这些实现提供了有关性能的特定保证,以及由此而提供的方法。还可以使用一些经过进一步细化的特征,例如 LinearSeq、IndexedSeq 和 SortedSet。下面的列表可能会得到改进。留下评论和建议,我会修复它。
基类和特征
Traversable
-- 基本集合类。只需使用foreach
即可实现。TraversableProxy
--Traversable
的代理。只需将self
指向真正的集合即可。TraversableView
-- 具有一些非严格方法的 Traversable。TraversableForwarder
-- 将大多数方法转发到底层
,除了toString
、hashCode
、equals< /code>、
stringPrefix
、newBuilder
、view
以及创建同类新可迭代对象的所有调用。mutable.Traversable
和immutable.Traversable
-- 与Traversable
相同,但限制集合类型。Iterable
类,例如MetaData
。Iterable
-- 可以为其创建Iterator
的集合(通过iterator
)。IterableProxy
、IterableView
、mutable
和immutable.Iterable
。Iterator
—— 不是Traversable
后代的特征。定义next
和hasNext
。CountedIterator
-- 定义count
的Iterator
,它返回到目前为止看到的元素。BufferedIterator
-- 定义head
,它返回下一个元素而不消耗它。Iterator
类,例如Source
。Maps
Map
-Tuple2
的Iterable
,它还提供了根据给定键检索值(元组的第二个元素)的方法(元组的第一个元素)。还扩展了PartialFunction
。MapProxy
--Map
的代理
。DefaultMap
-- 实现一些Map
抽象方法的特征。SortedMap
-- 其键已排序的Map
。immutable.SortMap
immutable.TreeMap
-- 实现immutable.SortedMap
的类。immutable.Map
immutable.MapProxy
immutable.HashMap
-- 通过键散列实现immutable.Map
的类。immutable.IntMap
-- 实现专用于Int
键的immutable.Map
的类。使用基于密钥的二进制数字的树。immutable.ListMap
-- 通过列表实现immutable.Map
的类。immutable.LongMap
-- 实现专用于Long
键的immutable.Map
的类。请参阅IntMap
。可变.Map
mutable.HashMap
-- 通过键散列实现mutable.Map
的类。mutable.ImmutableMapAdaptor
-- 从现有immutable.Map
实现mutable.Map
的类。mutable.LinkedHashMap
-- ?mutable.ListMap
-- 通过列表实现mutable.Map
的类。mutable.MultiMap
-- 一个类,每个键接受多个不同的值。mutable.ObservableMap
-- 一个mixin,当与Map
混合时,通过Publisher<向观察者发布事件/code> 接口。
mutable.OpenHashMap
-- 基于开放哈希算法的类。mutable.SynchronizedMap
-- 一个mixin,应与Map
混合以提供具有同步方法的版本。mutable.MapProxy
。序列
Seq
——元素序列。假设有明确定义的大小和元素重复。还扩展了PartialFunction
。IndexedSeq
-- 支持 O(1) 元素访问和 O(1) 长度计算的序列。IndexedSeqView
immutable.PagedSeq
--IndexedSeq
的实现,其中元素由通过构造函数传递的函数按需生成。immutable.IndexedSeq
immutable.Range
-- 一个分隔的整数序列,在低端封闭,在高端开放,并且有一个步长。immutable.Range.Inclusive
-Range
也在高端闭合。immutable.Range.ByOne
-- 步长为 1 的Range
。immutable.NumericRange
-- 更通用的Range
版本,可与任何Integral
配合使用。immutable.NumericRange.Inclusive
、immutable.NumericRange.Exclusive
。immutable.WrappedString
、immutable.RichString
-- 包装器,可以将String
视为Seq[Char],同时仍然保留
String
方法。我不确定它们之间有什么区别。mutable.IndexedSeq
mutable.GenericArray
-- 基于Seq
的类数组结构。请注意,“类”Array
是 Java 的Array
,它更多的是一种内存存储方法,而不是类。mutable.ResizableArray
-- 基于可调整大小数组的类使用的内部类。mutable.PriorityQueue
、mutable.SynchronizedPriorityQueue
-- 实现优先队列的类 -- 元素首先根据Ordering
出列的队列,以及最后排队的顺序。mutable.PriorityQueueProxy
--PriorityQueue
的抽象Proxy
。LinearSeq
-- 线性序列的特征,对于isEmpty
、head
和tail
具有高效的时间。immutable.LinearSeq
immutable.List
-- 不可变的单链接列表实现。immutable.Stream
-- 惰性列表。它的元素仅按需计算,但随后会被记忆(保存在内存中)。理论上可以是无限的。mutable.LinearSeq
mutable.DoublyLinkedList
-- 具有可变prev
、head
(elem
) 和的列表尾部
(下一个
)。mutable.LinkedList
-- 具有可变head
(elem
) 和tail
(下一步
)。mutable.MutableList
-- 内部用于实现基于可变列表的类的类。mutable.Queue
、mutable.QueueProxy
-- 针对 FIFO(先进先出)操作进行优化的数据结构。mutable.QueueProxy
--mutable.Queue
的代理
。SeqProxy
、SeqView
、SeqForwarder
immutable.Seq
immutable.Queue
-- 实现 FIFO 优化(先进先出)数据结构的类。可变
和不可变
队列没有共同的超类。immutable.Stack
-- 实现 LIFO 优化(后进先出)数据结构的类。两个mutable
immutable
堆栈没有共同的超类。immutable.Vector
-- ?scala.xml.NodeSeq
-- 扩展immutable.Seq
的专用 XML 类。immutable.IndexedSeq
-- 如上所示。immutable.LinearSeq
-- 如上所示。mutable.ArrayStack
-- 使用数组实现 LIFO 优化数据结构的类。据说比普通堆栈快得多。mutable.Stack
、mutable.SynchronizedStack
-- 实现 LIFO 优化数据结构的类。mutable.StackProxy
--mutable.Stack
的Proxy
..可变的.Seq
mutable.Buffer
-- 可以通过追加、前置或插入新成员来更改的元素序列。mutable.ArrayBuffer
--mutable.Buffer
类的实现,具有用于追加、更新和随机访问操作的恒定摊销时间。它有一些专门的子类,例如NodeBuffer
。mutable.BufferProxy
、mutable.SynchronizedBuffer
。mutable.ListBuffer
-- 由列表支持的缓冲区。它提供恒定时间追加和前置,大多数其他操作都是线性的。mutable.ObservableBuffer
-- 一个mixin特征,当混合到Buffer
时,通过Publisher< /code> 接口。
mutable.IndexedSeq
-- 如上所示。mutable.LinearSeq
-- 如上所示。集合
set
- 集合是一个集合,其中最多包含任何对象之一。bitset
- 一组作为bitset存储的整数。immutable.bitset
mutable.bitset
sortedset
- 订购元素的集合。不变。SortedSet
immutable.treeset
- 基于树的sortedset
的实现。setProxy
-代理
set> set
。不成熟的
immutable.hashset
- 基于元素hashing的set> set>的实现。
immutable.listset
- 基于列表的set>的实现。
immutable.setproxy
-代理
for InmundableSET
。。
Mutable.set
mutable.hashset
- 基于元素hashing的set> set>的实现。
。
set setMutable.MmutablesEtadaptor
- 从不变的linkedhashset
- 基于列表的Set>的实现。
observableset
- a mixin 特征,当与set set
混合时,通过Publisher 接口。
setProxy
-代理
set> set
。synchronizedset
- a mixin 特征,当与set set
混合时,通过Publisher 接口。
这是为了实现最大代码重用。类似的类别完成了具有特定结构(可遍历,地图等)类的混凝土通用实现。然后,旨在进行一般消费的类,然后覆盖可以选择的选定方法。
类的构建器,即知道如何以
map
,可以使用的方式来使用该类实例的对象,即由伴随对象中的方法创建。因此,为了构建类型X的对象,我需要从X的伴侣对象中获取该构建器。不幸的是,在Scala中,从类X到Object X中没有办法。 X,companion
的每个实例中定义的方法,它返回X类的伴随对象。尽管在普通程序中可能有某种用途,但其目标是在集合库中启用代码重用。
您不应该关心这一点。它们是隐含的,因此您无需弄清楚如何使其起作用。
这些隐含物存在是为了使集合上的方法在父类中定义,但仍返回相同类型的集合。例如,
map
方法是在traversablelike
上定义的,但是如果您在list list
上使用了list
list 代码>返回。Foreword
There's a 2.8 collection walk-through by Martin Odersky which should probably be your first reference. It has been supplemented as well with architectural notes, which will be of particular interest to those who want to design their own collections.
The rest of this answer was written way before any such thing existed (in fact, before 2.8.0 itself was released).
You can find a paper about it as Scala SID #3. Other papers in that area should be interesting as well to people interested in the differences between Scala 2.7 and 2.8.
I'll quote from the paper, selectively, and complement with some thoughts of mine. There are also some images, generated by Matthias at decodified.com, and the original SVG files can be found here.
The collection classes/traits themselves
There are actually three hierarchies of traits for the collections: one for mutable collections, one for immutable collections, and one which doesn't make any assumptions about the collections.
There's also a distinction between parallel, serial and maybe-parallel collections, which was introduced with Scala 2.9. I'll talk about them in the next section. The hierarchy described in this section refers exclusively to non-parallel collections.
The following image shows the non-specific hierarchy introduced with Scala 2.8:
All elements shown are traits. In the other two hierarchies there are also classes directly inheriting the traits as well as classes which can be viewed as belonging in that hierarchy through implicit conversion to wrapper classes. The legend for these graphs can be found after them.
Graph for immutable hierarchy:
Graph for mutable hierarchy:
Legend:
Here's an abbreviated ASCII depiction of the collection hierarchy, for those who can't see the images.
Parallel Collections
When Scala 2.9 introduced parallel collections, one of the design goals was to make their use as seamless as possible. In the simplest terms, one can replace a non-parallel (serial) collection with a parallel one, and instantly reap the benefits.
However, since all collections until then were serial, many algorithms using them assumed and depended on the fact that they were serial. Parallel collections fed to the methods with such assumptions would fail. For this reason, all the hierarchy described in the previous section mandates serial processing.
Two new hierarchies were created to support the parallel collections.
The parallel collections hierarchy has the same names for traits, but preceded with
Par
:ParIterable
,ParSeq
,ParMap
andParSet
. Note that there is noParTraversable
, since any collection supporting parallel access is capable of supporting the strongerParIterable
trait. It doesn't have some of the more specialized traits present in the serial hierarchy either. This whole hierarchy is found under the directoryscala.collection.parallel
.The classes implementing parallel collections also differ, with
ParHashMap
andParHashSet
for both mutable and immutable parallel collections, plusParRange
andParVector
implementingimmutable.ParSeq
andParArray
implementingmutable.ParSeq
.Another hierarchy also exists that mirrors the traits of serial and parallel collections, but with a prefix
Gen
:GenTraversable
,GenIterable
,GenSeq
,GenMap
andGenSet
. These traits are parents to both parallel and serial collections. This means that a method taking aSeq
cannot receive a parallel collection, but a method taking aGenSeq
is expected to work with both serial and parallel collections.Given the way these hierarchies were structured, code written for Scala 2.8 was fully compatible with Scala 2.9, and demanded serial behavior. Without being rewritten, it cannot take advantage of parallel collections, but the changes required are very small.
Using Parallel Collections
Any collection can be converted into a parallel one by calling the method
par
on it. Likewise, any collection can be converted into a serial one by calling the methodseq
on it.If the collection was already of the type requested (parallel or serial), no conversion will take place. If one calls
seq
on a parallel collection orpar
on a serial collection, however, a new collection with the requested characteristic will be generated.Do not confuse
seq
, which turns a collection into a non-parallel collection, withtoSeq
, which returns aSeq
created from the elements of the collection. CallingtoSeq
on a parallel collection will return aParSeq
, not a serial collection.The Main Traits
While there are many implementing classes and subtraits, there are some basic traits in the hierarchy, each of which providing more methods or more specific guarantees, but reducing the number of classes that could implement them.
In the following subsections, I'll give a brief description of the main traits and the idea behind them.
Trait TraversableOnce
This trait is pretty much like trait
Traversable
described below, but with the limitation that you can only use it once. That is, any methods called on aTraversableOnce
may render it unusable.This limitation makes it possible for the same methods to be shared between the collections and
Iterator
. This makes it possible for a method that works with anIterator
but not usingIterator
-specific methods to actually be able to work with any collection at all, plus iterators, if rewritten to acceptTraversableOnce
.Because
TraversableOnce
unifies collections and iterators, it does not appear in the previous graphs, which concern themselves only with collections.Trait Traversable
At the top of the collection hierarchy is trait
Traversable
. Its only abstract operation isThe operation is meant to traverse all elements of the collection, and apply the given operation f to each
element. The application is done for its side effect only; in fact any function result of f is discarded by
foreach.
Traversible objects can be finite or infinite. An example of an infinite traversable object is the stream
of natural numbers
Stream.from(0)
. The methodhasDefiniteSize
indicates whether a collection is possiblyinfinite. If
hasDefiniteSize
returns true, the collection is certainly finite. If it returns false, thecollection has not been not fully elaborated yet, so it might be infinite or finite.
This class defines methods which can be efficiently implemented in terms of
foreach
(over 40 of them).Trait Iterable
This trait declares an abstract method
iterator
that returns an iterator that yields all the collection’s elements one by one. Theforeach
method inIterable
is implemented in terms ofiterator
. Subclasses ofIterable
often override foreach with a direct implementation for efficiency.Class
Iterable
also adds some less-often used methods toTraversable
, which can be implemented efficiently only if aniterator
is available. They are summarized below.Other Traits
After
Iterable
there come three base traits which inherit from it:Seq
,Set
, andMap
. All three have anapply
method and all three implement thePartialFunction
trait, but the meaning ofapply
is different in each case.I trust the meaning of
Seq
,Set
andMap
is intuitive. After them, the classes break up in specific implementations that offer particular guarantees with regards to performance, and the methods it makes available as a result of it. Also available are some traits with further refinements, such asLinearSeq
,IndexedSeq
andSortedSet
.The listing below may be improved. Leave a comment with suggestions and I'll fix it.
Base Classes and Traits
Traversable
-- Basic collection class. Can be implemented just withforeach
.TraversableProxy
-- Proxy for aTraversable
. Just pointself
to the real collection.TraversableView
-- A Traversable with some non-strict methods.TraversableForwarder
-- Forwards most methods tounderlying
, excepttoString
,hashCode
,equals
,stringPrefix
,newBuilder
,view
and all calls creating a new iterable object of the same kind.mutable.Traversable
andimmutable.Traversable
-- same thing asTraversable
, but restricting the collection type.Iterable
classes, such asMetaData
, exists.Iterable
-- A collection for which anIterator
can be created (throughiterator
).IterableProxy
,IterableView
,mutable
andimmutable.Iterable
.Iterator
-- A trait which is not descendant ofTraversable
. Definenext
andhasNext
.CountedIterator
-- AnIterator
definingcount
, which returns the elements seen so far.BufferedIterator
-- Defineshead
, which returns the next element without consuming it.Iterator
classes, such asSource
, exists.The Maps
Map
-- AnIterable
ofTuple2
, which also provides methods for retrieving a value (the second element of the tuple) given a key (the first element of the tuple). ExtendsPartialFunction
as well.MapProxy
-- AProxy
for aMap
.DefaultMap
-- A trait implementing some ofMap
's abstract methods.SortedMap
-- AMap
whose keys are sorted.immutable.SortMap
immutable.TreeMap
-- A class implementingimmutable.SortedMap
.immutable.Map
immutable.MapProxy
immutable.HashMap
-- A class implementingimmutable.Map
through key hashing.immutable.IntMap
-- A class implementingimmutable.Map
specialized forInt
keys. Uses a tree based on the binary digits of the keys.immutable.ListMap
-- A class implementingimmutable.Map
through lists.immutable.LongMap
-- A class implementingimmutable.Map
specialized forLong
keys. SeeIntMap
.mutable.Map
mutable.HashMap
-- A class implementingmutable.Map
through key hashing.mutable.ImmutableMapAdaptor
-- A class implementing amutable.Map
from an existingimmutable.Map
.mutable.LinkedHashMap
-- ?mutable.ListMap
-- A class implementingmutable.Map
through lists.mutable.MultiMap
-- A class accepting more than one distinct value for each key.mutable.ObservableMap
-- A mixin which, when mixed with aMap
, publishes events to observers through aPublisher
interface.mutable.OpenHashMap
-- A class based on an open hashing algorithm.mutable.SynchronizedMap
-- A mixin which should be mixed with aMap
to provide a version of it with synchronized methods.mutable.MapProxy
.The Sequences
Seq
-- A sequence of elements. One assumes a well-defined size and element repetition. ExtendsPartialFunction
as well.IndexedSeq
-- Sequences that support O(1) element access and O(1) length computation.IndexedSeqView
immutable.PagedSeq
-- An implementation ofIndexedSeq
where the elements are produced on-demand by a function passed through the constructor.immutable.IndexedSeq
immutable.Range
-- A delimited sequence of integers, closed on the lower end, open on the high end, and with a step.immutable.Range.Inclusive
-- ARange
closed on the high end as well.immutable.Range.ByOne
-- ARange
whose step is 1.immutable.NumericRange
-- A more generic version ofRange
which works with anyIntegral
.immutable.NumericRange.Inclusive
,immutable.NumericRange.Exclusive
.immutable.WrappedString
,immutable.RichString
-- Wrappers which enables seeing aString
as aSeq[Char]
, while still preserving theString
methods. I'm not sure what the difference between them is.mutable.IndexedSeq
mutable.GenericArray
-- AnSeq
-based array-like structure. Note that the "class"Array
is Java'sArray
, which is more of a memory storage method than a class.mutable.ResizableArray
-- Internal class used by classes based on resizable arrays.mutable.PriorityQueue
,mutable.SynchronizedPriorityQueue
-- Classes implementing prioritized queues -- queues where the elements are dequeued according to anOrdering
first, and order of queueing last.mutable.PriorityQueueProxy
-- an abstractProxy
for aPriorityQueue
.LinearSeq
-- A trait for linear sequences, with efficient time forisEmpty
,head
andtail
.immutable.LinearSeq
immutable.List
-- An immutable, singlely-linked, list implementation.immutable.Stream
-- A lazy-list. Its elements are only computed on-demand, but memoized (kept in memory) afterwards. It can be theoretically infinite.mutable.LinearSeq
mutable.DoublyLinkedList
-- A list with mutableprev
,head
(elem
) andtail
(next
).mutable.LinkedList
-- A list with mutablehead
(elem
) andtail
(next
).mutable.MutableList
-- A class used internally to implement classes based on mutable lists.mutable.Queue
,mutable.QueueProxy
-- A data structure optimized for FIFO (First-In, First-Out) operations.mutable.QueueProxy
-- AProxy
for amutable.Queue
.SeqProxy
,SeqView
,SeqForwarder
immutable.Seq
immutable.Queue
-- A class implementing a FIFO-optimized (First-In, First-Out) data structure. There is no common superclass of bothmutable
andimmutable
queues.immutable.Stack
-- A class implementing a LIFO-optimized (Last-In, First-Out) data structure. There is no common superclass of bothmutable
immutable
stacks.immutable.Vector
-- ?scala.xml.NodeSeq
-- A specialized XML class which extendsimmutable.Seq
.immutable.IndexedSeq
-- As seen above.immutable.LinearSeq
-- As seen above.mutable.ArrayStack
-- A class implementing a LIFO-optimized data structure using arrays. Supposedly significantly faster than a normal stack.mutable.Stack
,mutable.SynchronizedStack
-- Classes implementing a LIFO-optimized data structure.mutable.StackProxy
-- AProxy
for amutable.Stack
..mutable.Seq
mutable.Buffer
-- Sequence of elements which can be changed by appending, prepending or inserting new members.mutable.ArrayBuffer
-- An implementation of themutable.Buffer
class, with constant amortized time for the append, update and random access operations. It has some specialized subclasses, such asNodeBuffer
.mutable.BufferProxy
,mutable.SynchronizedBuffer
.mutable.ListBuffer
-- A buffer backed by a list. It provides constant time append and prepend, with most other operations being linear.mutable.ObservableBuffer
-- A mixin trait which, when mixed to aBuffer
, provides notification events through aPublisher
interfaces.mutable.IndexedSeq
-- As seen above.mutable.LinearSeq
-- As seen above.The Sets
Set
-- A set is a collection that includes at most one of any object.BitSet
-- A set of integers stored as a bitset.immutable.BitSet
mutable.BitSet
SortedSet
-- A set whose elements are ordered.immutable.SortedSet
immutable.TreeSet
-- An implementation of aSortedSet
based on a tree.SetProxy
-- AProxy
for aSet
.immutable.Set
immutable.HashSet
-- An implementation ofSet
based on element hashing.immutable.ListSet
-- An implementation ofSet
based on lists.immutable.SetProxy
-- AProxy
for an immutableSet
.mutable.Set
mutable.HashSet
-- An implementation ofSet
based on element hashing.mutable.ImmutableSetAdaptor
-- A class implementing a mutableSet
from an immutableSet
.LinkedHashSet
-- An implementation ofSet
based on lists.ObservableSet
-- A mixin trait which, when mixed with aSet
, provides notification events through aPublisher
interface.SetProxy
-- AProxy
for aSet
.SynchronizedSet
-- A mixin trait which, when mixed with aSet
, provides notification events through aPublisher
interface.This was done to achieve maximum code reuse. The concrete generic implementation for classes with a certain structure (a traversable, a map, etc) is done in the Like classes. The classes intended for general consumption, then, override selected methods that can be optmized.
The builder for the classes, ie, the object which knows how to create instances of that class in a way that can be used by methods like
map
, is created by a method in the companion object. So, in order to build an object of type X, I need to get that builder from the companion object of X. Unfortunately, there is no way, in Scala, to get from class X to object X. Because of that, there is a method defined in each instance of X,companion
, which returns the companion object of class X.While there might be some use for such method in normal programs, its target is enabling code reuse in the collection library.
You aren't supposed to care about that. They are implicit precisely so that you don't need to figure out how to make it work.
These implicits exists to enable the methods on the collections to be defined on parent classes but still return a collection of the same type. For example, the
map
method is defined onTraversableLike
, but if you used on aList
you'll get aList
back.