序列
列表
- 最重要的序列类型是
List
类,支持在头部快速添加和移除条目,不支持随机访问。快速的头部添加和移除意味模式匹配很顺畅。
数组
- 数组中保存了一个序列的元素。并使用从
0
开始的随机访问。
- 数组中保存了一个序列的元素。并使用从
-
new Array[Int](5)
生成了一个大小为5
的列表,其中的每个元素值都为0
。使用array(index)
的方法来进行随机访问,是apply
函数的语法糖。
-
列表缓冲(list buffer)
-
ListBuffer
是一个可变对象,在列表尾部追加元素的时候比较高效,在头部添加和在尾部添加都是常量时间。可以使用+=
在尾部追加,使用+=:
在头部添加,完成构造之后,可以使用toList
方法来得到最终的List
。
数组缓冲(ArrayBuffer)
- 和
Array
很像,可以额外的从序列头部或者尾部进行操作,所有的Array
操作在ArrayBuffer
中都可以实现,不过稍微慢一些。随机访问偶尔需要线性时间,需要分配新的数组来保存缓冲的内容。和ListBuffer
一样,存在于可变包中。在创建的时候必须给出类型参数。
字符串StringOps
- 实现了许多序列方法,在
Predef
中存在从String
到StringOps
的隐式转换,可以将任何字符串当做序列来处理。
集合和映射
Scala
集合类库同时提供过了可变和不可变两个版本的集合和映射。
Set.png
Set
和Map
这两个定义出现了多次,当使用Set
或者Map
的时候,默认的是一个不可变的对象,因为在Predef
中定义了Map
和Set
指向的就是不可变包中的伴生对象。如果想要使用可变的版本,需要显示地做一次引入。
集合
- 集合中不存在重复元素,使用
==
来检查任意的两个元素是否相等。seperator=[,/]+
,表示分隔符是指其中的一个元素或者这个元素的多次重复。
- 集合中不存在重复元素,使用
-
- 常用的集合操作
// 不可变集合 set + 5 set - 3 set ++ List(5,6) set -- List(5,6) Set(1,2,4) & Set(1,2,3,4) 求交集 set.contains(12) Set.empty[String],创建一个空的集合 // 可变集合 set(1,2,4) += 4 set(1,2,4) -= 4 set(1,2,3) ++= List(2,3,4) set(1,2,3) --= List(1,23,4) set.clear
Map
- 写值:
map("hello") = 1; map("world") = 2
- 写值:
-
- 读取值:
map("hello")
,如果不存在这个key
,就会报错,使用map.get("hello")
的话,返回的是Option
类型的值。
常用的操作 // 不可变集合 val nums = Map(1 -> 2, 3 -> 4) nums + ( 4 -> 5) nums - 4 nums ++ List(( 4 -> 5), (6 -> 7)) nums -- List(( 4 -> 5), (6 -> 7)) nums.contains(1) nums(1) nums.keys nums.keySet nums.values nums.isEmpty // 可变集合 words += (1 -> 3) words -= 1 words ++= List(1-> 3, 4 -> 5) words --= List(1, 4)
- 读取值:
默认的集和映射
-
mutable.Set
的默认实现类是HashSet
,mutable.Map
的默认实现类是HashMap
。
-
- 对与不可变集合和映射来说,情况稍微复杂一些。
immutable.Set()
方法返回的类取决与传入的元素个数。对于少于5
个元素的集合,会有专门的特定大小的类与之对应:EmptySet,Set1,Set2,Set3,Set4
,如果元素个数大于5
,则使用HashSet
来实现,不可变的映射实现类似,使用的是HashMap
。从Set2
中移除一个元素可以得到Set1
。
- 对与不可变集合和映射来说,情况稍微复杂一些。
排序的集合和映射
-
Scala
集合类库提供了SortedSet
和SortedMap
特质,分别由TreeSet
和TreeMap
实现。TreeMap
排序的是键的顺序。具体顺序由Ordered
特质决定,集合或者映射的键的类型必须混入或者能够被隐式地转换为Ordered
。
可变和不可变集合类之间的选择
- 在元素不多的情况下,使用不可变集合通常比可变集合存储得更紧凑。
- 为了将不可变集合转到可变集或者逆操作,
Scala
提供过了一些语法糖。如果发现a += b
的操作,a
并不存在+=
操作时,Scala
将试图将其解读为a = a + b
。同样的理念适用于任何以=
结尾的方法。这样的好处是只需引入可变版本的Map
就可以覆盖实现,避免了大面积上代码的改动。这样的特殊语法不仅适用于集合,也适用于任何值。
- 为了将不可变集合转到可变集或者逆操作,
初始化集合
- 创建和初始化一个集合最常见的方式是将初始元素传入所选集合的伴生对象的工厂方法中,只需要将元素放在伴生对象名后的圆括号中即可。
Scala
编译器会将其转换为伴生对象apply
方法的调用。编译器可以通过初始元素的类型来确定集合的类型。但也可以在创建集合时指定跟编译器所选的不同类型。尤其是对可变的集合以及映射。val a = mutable.Set(1,2,3) a += "string"
a
并不会自动转换为Set[Any]
,这需要在定义的时候明确指出a
的类型为Any
。因为可变集合和映射实在原来的集合上做修改,不可变集合是copy
了原来的集合进行了修改。
转换成数组或者列表
- 直接使用
toList
或toArray
方法,需要对集合元素做拷贝,对于大型集合会比较费时,但一般许多集合本来元素就不多,所以因为拷贝带来的性能开销并不高。
- 直接使用
- 可变集合和不可变集合之间的转变:使用
empty
和++
以及++=
操作。
- 可变集合和不可变集合之间的转变:使用
immutable.Set.empty[String] ++ muteSet mutable.Set.empty[Stting] ++= immuteSet
元组
- 元组可以用来定义一些简单的数据结构,元组中可以存在不同类型的数据,如果一个类的作用就是存储不同类型的数据,可以使用元组来替代这个类。但如果这个类中的字段存在某种意义的时候最好还是定义为类,还可以利用编译器来进行检查。
网友评论