scala同时支持
不可变集合和可变集合
,因为不可变集合可以安全的并发访问,所以他也是默认使用的集合库类。在scala中,对于几乎所有的集合类,都提供了可变和不可变两个版本:
- 不可变集合 :指的是集合内的元素一旦初始化就不可再进行更改,任何对集合的改变都将生成一个新的集合。不可变集合都在
scala.collection.immutable
这个包下,使用时无需手动导包;- 可变集合:指的是这个集合本身可以动态变化,且可变集合提供了改变集合内元素的方法。都在
scala.collection.mutable
这个包下,使用时需要手动导包。
小技巧:
- 1、可变集合比不可变集合更加丰富。如在Seq集合中,增加了Buffer集合,我们常用的有:ArrayBuffer和ListBuffer。
- 2、当我们接触一个新的继承体系时,建议采用学顶层,用底层的方式。
- 顶层定义的是整个继承体系所共有的内容;
- 底层才是具体的体现、实现;
1、Traversable
Traversable是一个特质(trait),他是其他所有接的父特质,他的子特质imutable.Traversable和mutable.Traversable分别是不可变集合和可变集合的父特质,集合中大部分通用方法都是在这个特质方法中定义的。因此了解他的功能对学习其他集合类至关重要。
// 实例1.1 创建Traversable对象
// 创建空的Traversable对象
// 方式一:通过empty方法实现
val t1 = Traversable.empty[Int]
// 方式二:通过小括号实现
val t2 = Traversable[Int]()
// 方式三:通过Nil实现
val t3 = Nil
// 创建带参数的Traversable对象
// 方式一:通过toTraversable()方法实现
val t4 = List(1,2,3).toTraversable()
// 方式二:通过Traversable的伴生对象的apply()方法来实现
val t5 = Traversable(1, 2, 3)
// 实例1.2 转置Traversable集合
// 定义集合
val t1: Traversable[Traversable[Int]] = Traversable(Traversable(1,4,7), Traversable(2,5,8), Traversable(3,6,9))
// 转置
val t2 = t1.transpose
println(t2)
// 实例1.3 拼接集合
// 通过++方式拼接数据会创建大量的临时集合(每++一次就会创建一个新的临时集合),针对这种情况,我们可以通过concat方法来实现。该方法会预先计算出所需集合大小,然后生成一个集合,减少了中间无用的临时集合
val t1 = Traversable(1, 2, 3)
val t2 = Traversable(2, 3, 4)
val t4 = Traversable.concat(t1, t2, t2)
println(t4)
// 利用偏函数筛选元素
// 通过collect()方法实现偏函数结合集合来使用,从而来从集合中筛选指定的数据
def collect[B](pf: PartialFunction[A, B]): Traversable[B]
/* 解释:
* 1、[B]表示通过偏函数处理后,返回值的数据类型;
* 2、pf: PartialFunction[A, B] 表示collect()方法需要传入一个偏函数对象;
* 3、Traversable[B] 表示返回的具体数据的集合;
*/
// 样例
val t1 = (1 to 10).toTraversable // 底层是vector
val t2 = Traversable(1, 2, 3, 4, 5, 6, 7, 8, 9) // 底层是List
// 通过collect()方法筛选出集合中所有的偶数:val t3 = t1.collect(偏函数对象)
// 方式1:分解版
val pf:PartialFunction[Int, Int] = {case x if x%2==0 => x}
val t3 = t1.collect(pf)
// 方式2:合并版
val t4 = t2.collect({case x if x%2==0 => x})
// 判断元素是否合法
// 如果遇到判断集合中所有的元素是否都满足指定的条件,或者任意元素满足指定条件的需求,则可以使用forall()和exists()方法
// forall() 如果集合中所有元素都满足条件,则返回true,否则返回false;
// exists() 如果集合中任意一个元素满足指定的条件就返回true,否则返回false;
val t1 = Traversable(1,2,3,4,5,6)
println(t1.forall(_%2==0))
println(t1.exists(_%2==0))
// 利用偏函数筛选元素
def collect[B](pf: PartialFunction[A, B]): Traversable[B]
/* 解释:
* 1、[B]表示通过偏函数处理后,返回值的数据类型;
* 2、pf: PartialFunction[A, B] 表示collect()方法需要传入一个偏函数对象;
* 3、Traversable[B] 表示返回的具体数据的集合;
*/
获取集合中的指定元素:
-
head
, 获取集合中的第一个元素,如果元素不存在,则抛出NoSuchElementException
异常; -
last
, 获取集合的最后一个元素,如果元素不存在,则抛出NoSuchElementException
异常; -
headOption
, 获取集合的第一个元素,返回值类型是Option; -
lastOption
, 获取集合的最后一个元素,返回值类型是Option; -
find
, 查找集合中第一个满足指定条件的元素; -
slice
, 截取集合中的一部分元素。
聚合函数:
-
sum()
,求和; -
count()
,计算元素个数; -
product()
,计算元素乘积; -
max()
,获取最大值; -
min()
,获取最小值;
集合类型转换:
-
toxxx
, 如toSeq
,toList
,toSet
,toArray
... ...
填充元素
如果想要往集合中快速添加相同元素,就需要用到fill()
和iterate()
方法,而如果是想生成指定间隔的队列元素,就可以通过range()
方法。
-
fill()
方法,快速生成指定数量的元素,如Traversable.fill(5)(Random.nextInt(100))
; -
iterate()
方法,根据指定条件生成指定个数的元素。如Traversable.iterate(1,5)(_*10)
,其中1表示初始化值,5表示最终要获取的元素个数,_*10表示函数对象,具体规则,生成结果(1, 10, 100, 1000, 10000); -
range()
方法,生成某个区间内的指定间隔的所有元素;
zipWithIndex, sameElement
Seq获取指定元素索引值的方法
-
indexOf
, 获取指定元素在列表第一次出现的位置; -
lastIndexOf
, 获取指定元素在列表最后一次出现的位置; -
indexWhere
, 获取满足条件的元素,在集合中第一次出现的索引; -
lastIndexWhere
, 获取满足条件的元素,在集合中最后一次出现的索引; -
indexOfSlice
, 获取指定的子序列在集合中第一次出现的位置。
Seq判断是否包含指定数据
-
startsWith
, 判断集合是否以指定的子序列开头; -
endsWith
, 判断集合是否以指定的子序列结尾; -
contains
, 判断集合是否包含某个指定的数据; -
containsSlice
, 判断集合是否包含某个指定的子序列。
Seq修改指定元素
-
updated
, 修改指定索引位置的元素为指定的值; -
patch
, 修改指定区间的元素为指定的值。
网友评论