本章主要介绍Scala中的集合类型,主要包括:Array, ListBuffer, Arraybuffer, Set, MapTuple

  

一、序列

  序列类型的对象中包含多个按顺序排列好的元素,可以访问其中特定位置的元素。序列类型主要包括ListArrayListBufferArrayBuffer

1、List

  List在前一章已经介绍过,略。

2、Array

  数组在很多编程语言中都会用到。下面代码中包括了如何定义一个Array类型变量,如何在定义Array变量时赋初始值,以及如何访问和更新特定位置的元素。

val fiveInts = new Array[Int](5) // 生成一个长度为5的数组
val fiveToOne = Array(5, 4, 3, 2, 1) // 生成一个长度为5的数组并初始化
fiveInts(0) = fiveToOne(4) // 访问指定位置上的元素并赋值
fiveInts

  运行结果如下,

  

  Scala中的数组和Java中的数组是相同的。

3、ListBuffer

  ListBuffer类型的完整路径名为scala.collection.mutable.ListBuffer

  在ListBuffer对象的前面和后面增加新元素都非常的方便,使用+=方法在该对象后新增元素,使用+=:在该对象前新增元素。当元素添加完毕后,调

toList方法将ListBuffer对象转化成List,使得构建List对象更加高效。

import scala.collection.mutable.ListBuffer

val buf = new ListBuffer[Int]
buf += 1
buf += 2
buf
3 +=: buf
buf.toList

  结果如下,

  

4、ArrayBuffer

  ArrayBuffer的完整路径是scala.collection.mutable.ArrayBufferArrayBufferArray类似,支持所有Array上的操作。

  使用ArrayBuffer的好处是,定义时可以不指定长度。并且在ArrayBuffer的头部和尾部添加或移除元素更加便捷。

import scala.collection.mutable.ArrayBuffer

val buf = new ArrayBuffer[Int]()
buf += 12
buf += 15
buf
buf.length
buf(0)

  运行结果如下,

  

5、String

  String对象本质上是字符序列。可以直接在String对象上进行遍历,遍历的内容就是该对象的每一个字符元素。

val a = "abcdefg"
a.foreach(println) def hasUpperCase(s: String) = s.exists(_.isUpper)
hasUpperCase("Robert Frost")
hasUpperCase("e e cummings")

  运行结果如下,

  

二、SetMap

  Scala中同时提供了mutableimmutable类型的SetMap类型。有关SetMap类型的类继承关系,如下图所示,

  Map类继承关系:

  

  Set类继承关系:

  

  从上面两图可以看到,分别有三个MapSet命名的trait,只不过这三个trait位于不同的package中。直接使用Map或者Set,在默认情况下,使用的是imutable这个。如果想要实现mutable类型的SetMap需要显式的import。

  下面分别介绍SetMap类型。

1、Set

  Set对象中不会包含重复元素。下面将一个String类型变量切割成单词,然后生成一个Set对象。

val text = "See Spot run. Run, Spot. Run!"
val wordsArray = text.split("[ !,.]+") val words = mutable.Set.empty[String]
for (word <- wordsArray)
words += word.toLowerCase words

  运行结果如下,最终的Set对象中只包含了三个不重复的元素。

  

  Set对象上的常用操作列表如下,注意区分哪些是mutable类型的Set,哪些是imutable类型的Set

操作符 作用及结果
val nums = Set(1, 2, 3) 生成一个新的Set对象,并初始化
nums + 5 新增一个元素,得到一个新的Set对象,结果为Set(1, 2, 3, 5)
nums - 3 删除Set中的一个元素,结果为Set(1, 2, 5)
nums ++ List(5, 6) List中的元素全部增加到Set中,结果为Set(1, 2, 3, 5, 6)
nums -- List(1, 2) 去除Set中的包含在List中的元素,结果为Set(3)
nums $ Set(1, 3, 5, 7) 返回两个Set对象中共有的元素,结果为Set(1, 3)
nums.size 获取当前Set中的元素个数,结果为3
nums.contains(3) 判断nums中是否包含指定元素,结果为true
import scala.collection.mutable 引入mutable类型的Set对象
val words = mutable.Set.empty[String] 生成一个空的mutable.Set对象
words += "the" words中增加元素,words的内容随之发生变化,结果为Set(the)
words -= "the" words中移除元素,此时words为空,结果为Set()
words ++= List("do", "re", "mi") List中的元素全部添加到words中,结果为Set(do, re, mi)
words --= List("do", "re") List中包含的元素从words中移除,结果为Set(mi)
words.clear 清空words,移除全部元素,结果为Set()

2、Map

  直接看示例,展示了如何新建Map对象,如何往Map对象中添加键值对,以及如何从Map对象中获取指定keyvalue值。

val map = mutable.Map.empty[String, Int]
map("hello") = 1
map("there") = 2
map
map("hello")

  运行结果为,

  

  Map上的常见操作如下,注意区分哪些是mutable类型的Map对象,哪些是imutable类型的Map对象。

操作符 作用及结果
val nums = Map("i" -> 1, "ii" -> 2) 生成一个新的Map对象,并初始化
nums + ("vi" -> 6) 新增一个元素,得到一个新的Map对象,结果为Map(i -> 1, ii -> 2, vi -> 6)
nums - "ii" 删除Map中的一个元素,结果为Map(i -> 1)
nums ++ List("iii" -> 3, "v" -> 5) List中的元素全部增加到Map中,结果为Map(i -> 1, ii -> 2, iii -> 3, v -> 5)
nums -- List("i", "ii") 去除Map中的key为包含在List中的元素,结果为Map()
nums.size 获取当前Map中的键值对个数,结果为2
nums.contains("ii") 判断nums中是否包含指定keyii的键值对,结果为true
nums("ii") 获取指定keyvalue值,结果为2
nums.keys 获取当前nums对象中所有的key
nums.keySet 获取当前nums对象中所有的key值 ,以Set形式返回。结果为Set(i, ii)
nums.values 获取当前nums对象中所有的value
nums.isEmpty 判断nums是否为空,结果为false
import scala.collection.mutable 引入mutable类型的Map对象
val words = mutable.Map.empty[String, Int] 生成一个空的mutable.Map对象
words += ("one" -> 1) words中增加元素,words的内容随之发生变化,结果为Map(one -> 1)
words -= "one" words中移除元素,此时words为空,结果为Map()
words ++= List("one" -> 1, "two" -> 2, "three" -> 3) List中的键值对全部添加到words中,结果为Map(one -> 1, two -> 2, three -> 3)
words --= List("one", "two") List中包含的keywords中移除,结果为Map(three -> 3)

3、TreeMapTreeSet的其他子类

  MapSet还有其他形式的子类,比如TreeSetTreeMap

  前面展示的MapSet中的元素都是无序的,需要有序的MapSet可以使用TreeMapTreeSet类型。TreeSet是对其中的元素进行排序,TreeMap是对其中键值对的Key进行排序,底层使用的是红黑树。

import scala.collection.immutable.TreeSet
val ts = TreeSet(9, 3, 1, 8, 0, 2, 7, 4, 6, 5)
val cs = TreeSet('f', 'u', 'n')
import scala.collection.immutable.TreeMap
var tm = TreeMap(3 -> 'x', 1 -> 'x', 4 -> 'x')
tm += (2 -> 'x')
tm

  运行结果如下,

  

三、初始化集合

  在前面的示例代码中可以看到,一般是调用该类型伴生对象的工厂方法,并且传入初始参数值来初始化一个集合的对象。比如

List(1, 2, 3)
Set('a', 'b', 'c')
import scala.collection.mutable
mutable.Map("hi" -> 2, "three" -> 5)
Array(1.0, 2.0, 3.0)

  运行结果如下,从结果可以看到,Scala编译器会根据传入初始参数的类型,推断出集合中的元素类型。

  

  但是,对于mutable类型的集合对象来说,由于需要动态的增加新元素,最好在初始化集合对象时手动声明其类型,否则会出现以下报错情况。

val stuff = mutable.Set(42)
stuff += "abracadabra"

  报错如下,由于初始化时传入的是Int类型元素,Scala编译器会认为该Set对象中的元素必须是Int类型,当新增一个String类型元素时,就会报出类型不匹配的错。

  

  正确的做法如下,

val stuff: mutable.Set[Any] = mutable.Set(42)
stuff += "abracadabra"

  结果如下,

  

四、元组

  Scala中提供一种特殊的类型,TupleTuple中可以存储不同类型的元素,元组元素用圆括号包围。如下所示

val t = (1, "hello", Console)

  访问Tuple中的元素,使用_1表示第一个元素,_2表示第二个元素,以此类推。比如

t._1
t._2
t._3

  运行结果如下,

  

  也可以在生成Tuple对象时直接指定各元素对应的变量名,相当于同时声明并初始化多个元素。需要注意的是变量个数与元组中元素个数需要保持一致。

val (t1, t2, t3) = (1, "hello", Console)

  结果如下,

  

Programming In Scala笔记-第十七章、Scala中的集合类型的更多相关文章

  1. Programming In Scala笔记-第十一章、Scala中的类继承关系

    本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...

  2. Programming In Scala笔记-第五章、Scala中的变量类型和操作

    这一章的一些基础性的东西,主要包括Scala中的基本变量类型,以及相关的一些操作符. 一.简单类型 下表中列出Scala语言中的基本类型,以及其字节长度,其中Byte, Short, Int, Lon ...

  3. Programming In Scala笔记-第七章、Scala中的控制结构

    所谓的内建控制结构是指编程语言中可以使用的一些代码控制语法,如Scala中的if, while, for, try, match, 以及函数调用等.需要注意的是,Scala几乎所有的内建控制结构都会返 ...

  4. [汇编学习笔记][第十七章使用BIOS进行键盘输入和磁盘读写

    第十七章 使用BIOS进行键盘输入和磁盘读写 17.1 int 9 中断例程对键盘输入的处理 17.2 int 16 读取键盘缓存区 mov ah,0 int 16h 结果:(ah)=扫描码,(al) ...

  5. C++ primer plus读书笔记——第14章 C++中的代码重用

    第14章 C++中的代码重用 1. 使用公有继承时,类可以继承接口,可能还有实现(基类的纯虚函数提供接口,但不提供实现).获得接口是is-a关系的组成部分.而使用组合,类可以获得实现,但不能获得接口. ...

  6. Programming In Scala笔记-第六章、函数式对象

    这一章主要是以定义和完善一个有理数类Rational为线索,分析和介绍有关类定义,构造函数,方法重写,变量定义和私有化,以及对操作符的定义等. 一.Rational类定义和构造函数 1.定义一个空类 ...

  7. Programming In Scala笔记-第四章、类和对象

    类似于Java,Scala中也有类和对象的概念. 一.类.属性和方法 1.类 类是对一类事物的抽象,当一个类被定义后,就可以以该定义为模板,定义该类的一系列对象.比如说有以下一个模板 人类: 有姓名: ...

  8. 《linux内核设计与实现》读书笔记第十七章

    第17章 设备与模块 四种内核成分 设备类型:在所有 Unix 系统中为了统一普通设备的操作所采用的分类. 模块: Linux 内核中用于按需加载和卸载目标码的机制. 内核对象:内核数据结构中支持面向 ...

  9. The C++ Programming Language 学习笔记 第6章 表达式和语句

    1.关于strcpy函数. 书中说c风格的字符串尽量少用,strcpy这样的函数应该也要少用.这里讲这个函数主要是要通过本章课后练习第十题来讲一下前面提及的要点.巩固一下前几章的知识.写了一段,本来感 ...

随机推荐

  1. JavaScript push() 方法

    定义和用法: push() :可向数组的末尾添加一个或多个元素,并返回新的长度. 语法 arrayObject.push(newelement1,newelement2,....,newelement ...

  2. 四,前端---constructor与prototype

    这里对于constructor 和 prototype做一个简单的介绍,旨在让大家有一个简单的了解与认识 1:定义与用法 prototype:属性使您有能力向对象添加属性和方法. constructo ...

  3. further occurrences of HTTP header parsing errors will be logged at DEBUG level.错误

    今天进行项目测试的时候出现了further occurrences of HTTP header parsing errors will be logged at DEBUG level.错误,查了半 ...

  4. [LeetCode] Kth Smallest Number in Multiplication Table 乘法表中的第K小的数字

    Nearly every one have used the Multiplication Table. But could you find out the k-th smallest number ...

  5. shell入门笔记2:字符串、数组、echo与printf

    说明: 本文是关于http://c.biancheng.net/cpp/shell/的相关笔记 shell字符串 字符串可以用单引号,也可以用双引号,也可以不用引号. 1 #!/bin/bash 2 ...

  6. ConcurrentHashMap源码分析(1.8)

    0.说明 1.ConcurrentHashMap跟HashMap,HashTable的对比 2.ConcurrentHashMap原理概览 3.ConcurrentHashMap几个重要概念 4.Co ...

  7. [JSOI2015]非诚勿扰

    Description [故事背景] JYY赶上了互联网创业的大潮,为非常勿扰开发了最新的手机App实现单身 大龄青年之间的“速配”.然而随着用户数量的增长,JYY发现现有速配的算法似 乎很难满足大家 ...

  8. [Codeforces]852A - Digits

    题目大意:给一个10^200000以内的数字,支持一种操作:在数字之间加若干个加号,把原数字变为加法运算后的结果,要求在三次操作内把数字变成个位数,输出方案. 做法:直观的想法是每两位之间都塞加号,事 ...

  9. hdu 1890 splay树

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  10. ubuntu Linux下C语言open函数打开或创建文件与read,write函数详细讲解

    open(打开文件) 相关函数 read,write,fcntl,close,link,stat,umask,unlink,fopen 表头文件 #include<sys/types.h> ...