scala 集合总结(SeqMapSetListTupleOption)
Posted nefu-ljw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了scala 集合总结(SeqMapSetListTupleOption)相关的知识,希望对你有一定的参考价值。
文章目录
https://docs.scala-lang.org/scala3/book/collections-classes.html
https://docs.scala-lang.org/overviews/collections-2.13/overview.html
scala 集合的三大类型
从较高的层次来看 Scala 集合,主要有以下三个类别可供选择:
- Sequences是元素的顺序集合,可以是索引的(如数组)或线性的(如链表)
- Maps包含键/值对的集合,类似于Java的
Map
、Python的dict
- Sets是唯一元素的无序集合
所有这些都是基本类型,并且具有用于特定目的的子类型,例如并发、缓存和流式处理。除了这三个主要类别之外,还有其他有用的集合类型,包括ranges, stacks, queues。
下图显示了scala.collection
包中的集合类型。这些都是高级抽象类或特征,通常具有不可变和可变的实现。
scala.collection.immutable(不可变集合)
scala.collection.immutable
包中的集合保证对每个人都是不可变的。这样的集合在创建后就永远不会改变。因此,您可以相信在不同时间点重复访问相同集合值将始终产生具有相同元素的集合这一事实。
下图显示包scala.collection.immutable
中的所有集合:
scala.collection.mutable(可变集合)
scala.collection.mutable
包中的集合具有一些更改集合的操作。因此,处理可变集合意味着您需要了解哪些代码在何时更改了哪个集合。
下图显示包scala.collection.mutable
中的所有集合:
默认情况下,Scala 总是选择不可变集合。例如,如果只是编写Set
而没有任何前缀或没有 Set
从某处导入,将获得一个不可变集,如果编写 Iterable
将获得一个不可变的可迭代集合,因为这些是从scala
包中导入的默认绑定。
常用集合总结
集合类型 | 不变的 | 可变的 | 描述 |
---|---|---|---|
List | ✓ | 线性(链表)、不可变序列。List[T] 是类型 T 的链表。 | |
Vector | ✓ | 一个索引的、不可变的序列。 | |
LazyList | ✓ | 惰性不可变链表,其元素仅在需要时才计算;适用于大型或无限序列。 | |
ArrayBuffer | ✓ | 可变索引序列的首选类型。 | |
ListBuffer | ✓ | 当你想要一个可变的List ;通常转换为List 。 | |
Map | ✓ | ✓ | 由成对的键和值组成的可迭代集合。可通过键检索值。 |
Set | ✓ | ✓ | 没有重复元素的可迭代集合。Set中元素类型相同。 |
如上所示,Map
和Set
有不可变和可变版本。
List
、Vector
、LazyList
、ArrayBuffer
、ListBuffer
均是Seq
的子类。
其他集合:
https://www.tutorialspoint.com/scala_collections/scala_collections_overview.htm
集合类型 | 描述 |
---|---|
Tuple | 与数组或列表不同,元组可以包含不同类型的对象,适合存放异构类型元素。 |
Option | Option[T] 为给定类型的零个或一个元素提供容器。 |
Iterator
:迭代器不是集合,而是一种逐个访问集合元素的方式。
使用时应该选择哪个Seq子类
选择序列(顺序集合元素)时,您有两个主要决定:
- 序列应该被索引(如数组),允许快速访问任何元素,还是应该作为线性链表实现?
- 你想要一个可变的还是不可变的集合?
此处显示了针对可变/不可变和索引/线性组合的推荐的通用“转到”顺序集合:
类型/类别 | 不变的 | 可变的 |
---|---|---|
索引 | Vector | ArrayBuffer |
线性(链表) | List | ListBuffer |
例如,如果您需要一个不可变的索引集合,通常您应该使用Vector
。相反,如果您需要一个可变的索引集合,请使用ArrayBuffer
。
Vector 与 List 的比较
https://stackoverflow.com/a/35115252/17434375
- List 是一个单链表,仅提供线性迭代和恒定时间前置,头/尾分解。
- Vector 是一个 base-32 整数 trie,即它是一种节点度数为 32 的搜索树。使用这种结构,Vector 可以相当快地 O(log_32(n)) 提供大多数常见操作。这适用于头/尾中的前置、追加、更新、随机访问、分解(prepend, append, update, random access, decomposition in head/tail)。按顺序迭代是线性时间。
这看起来好像在几乎所有情况下 Vector 都是 List 的一个很好的替代品,但是前置、分解和迭代通常是函数式程序中对序列的关键操作,并且这些操作的常量对于 vector 来说高得多,由于其更复杂的结构。
对于顺序操作,List 可能要快一点;对于大量的随机访问和不同的更新,应该使用 Vector。
Seq 与 List 的关系
Seq
是具有定义的元素顺序的 Iterable 。提供了一种apply()
索引方法,范围从 0 到Seq长度。
List
是作为不可变链表实现的 Seq 。它最适用于具有后进先出 (LIFO) 访问模式的情况。
https://stackoverflow.com/a/44787827/17434375
Seq
is a trait thatList
implements.
我的理解是:Seq是上层接口抽象,List是下层实现(不可变链表)。这样设计有个好处,就是定义函数时参数类型设为Seq,在调用的时候传入参数可以是Seq子类(比如 List 或者 Vector 等)。Vector的好处是能更快随机访问,以及更适合并行算法。
如果定义Seq时未指定容器类型,则底层数据结构默认为List
。
scala> val a = Seq(1,2,3) // 不指明a的数据类型就默认是List
a: Seq[Int] = List(1, 2, 3)
// 等价于
scala> val a: Seq[Int] = List(1,2,3)
a: Seq[Int] = List(1, 2, 3)
Seq 与 Array 的关系
https://www.baeldung.com/scala/array-vs-wrappedarray
Scala程序最终被编译为.class文件运行在JVM虚拟机中,所以它是JVM下的语言一种,在实际的大数据开发任务当中,Java和Scala都运行于JVM之上,也能更好地集成。
Scala Array对应于Java中的Array。
scala写法
val simpleArray: Array[Int] = Array(1, 2, 3, 4, 5)
java写法
int[] simpleArray = new int[]1, 2, 3, 4, 5;
这两种代码编译生成的字节码相同,在字节码级别使用原始类型。Scala Array[Int]
在底层被转换为 Java int[]
数组。这同样适用于Double、Float、Long和其他“盒装”类型。
Scala 提供了比 Java 更多的Array类功能:
- 数组是通用的,所以我们可以创建一个Array[T],其中 T 可以是抽象类型或具体类型。
- 数组是Seq兼容的。我们可以在需要 Seq[T] 的地方传递 Array[T]。
- 数组支持所有序列操作。
因此,即使 Scala Array映射到原生 Java 数组,我们也可以将 Array 用作 Seq。
在scala 2.13版本,这是通过将Array隐式转换为ArraySeq(ArraySeq是Seq的子类)来完成的。
Scala 调用wrapIntArray()方法将Array转换为ArraySeq实例。
注意不同scala版本的隐式转换不一样:
// Scala 2.13+
scala> val a:Seq[Int] = Array(1,2,3)
// warning: method copyArrayToImmutableIndexedSeq in class LowPriorityImplicits2 is deprecated (since 2.13.0): Implicit conversions from Array to immutable.IndexedSeq are implemented by copying; Use the more efficient non-copying ArraySeq.unsafeWrapArray or an explicit toIndexedSeq call
a: Seq[Int] = ArraySeq(1, 2, 3)
// Scala 2.12
scala> val a:Seq[Int] = Array(1,2,3)
a: Seq[Int] = WrappedArray(1, 2, 3)
// 等价于
scala> val a = Array(1,2,3)
a: Array[Int] = Array(1, 2, 3)
scala> a.toSeq
res: Seq[Int] = WrappedArray(1, 2, 3)
以上是关于scala 集合总结(SeqMapSetListTupleOption)的主要内容,如果未能解决你的问题,请参考以下文章