Scala入门到精通——第四节 Set、Map、Tuple、队列操作实战

本节主要内容

  1. mutable、immutable集合
  2. Set操作实战
  3. Map操作实战
  4. Tuple操作实战
  5. 队列操作实战
  6. 栈操作实战

mutable、immutable集合

以下内容来源于scala官方文档:
http://www.scala-lang.org/docu/files/collections-api/collections.html

Scala collections systematically distinguish between mutable and immutable collections. A mutable collection can be updated or extended in place.
This means you can change, add, or remove elements of a collection as a side effect. Immutable collections, by contrast, never change. You have still operations that simulate additions, removals, or updates,
but those operations will in each case return a new collection and leave the old collection unchanged.
//大致意思是:scala中的集合分为两种,一种是可变的集合,另一种是不可变的集合
//可变的集合可以更新或修改,添加、删除、修改元素将作用于原集合
//不可变集合一量被创建,便不能被改变,添加、删除、更新操作返回的是新的集合,老集合保持不变

scala中所有的集合都来自于scala.collection包及其子包mutable, immutable当中

//scala.collection.immutable包中的集合绝对是不可变的,函数式编程语言推崇使用immutable集合
A collection in package scala.collection.immutable is guaranteed to be immutable for everyone. Such a collection will never change after it is created.
Therefore, you can rely on the fact that accessing the same collection value repeatedly at different points in time will always yield a collection with the same elements.
//scala.collection.immutable包中的集合在是可变的,使用的时候必须明白集合何时发生变化
A collection in package scala.collection.mutable is known to have some operations that change the collection in place.
So dealing with mutable collection means you need to understand which code changes which collection when.

//scala.collection中的集合要么是mutalbe的,要么是immutable的
//同时该包中也定义了immutable及mutable集合的接口
A collection in package scala.collection can be either mutable or immutable. For instance,
collection.IndexedSeq[T] is a superclass of both collection.immutable.IndexedSeq[T] and collection.mutable.IndexedSeq[T] Generally,
the root collections in package scala.collection define the same interface as the immutable collections,
and the mutable collections in package scala.collection.mutable typically add some side-effecting modification operations to this immutable interface.

在scala中,默认使用的都是immutable集合,如果要使用mutable集合,需要在程序中引入

import scala.collection.mutable
//由于immutable是默认导入的,因此要使用mutable中的集合的话
//使用如下语句
scala> val mutableSet=mutable.Set(1,2,3)
mutableSet: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
//不指定的话,创建的是immutable 集合
scala> val mutableSet=Set(1,2,3)
mutableSet: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

直接使用Set(1,2,3)创建的是immutable集合,这是因为当你不引入任何包的时候,scala会默认导入以几个包:

Predef对象中包含了Set、Map等的定义

scala集合类的层次结构:

scala.collection包中的集合类层次结构如下图:

These are all high-level abstract classes or traits, which generally have mutable as well as immutable implementations.

scala.collection.immutable包中的类层次结构:

scala.collection.mutable包中的类层次结构:

可变集合与不可变集合对应关系:

Set操作实战

1 Set(集)是一种不存在重复元素的集合,它与数学上定义的集合是对应的

//定义一个集合
//这里使用的是mutable
scala> val numsSet=Set(3.0,5)
numsSet: scala.collection.mutable.Set[Double] = Set(5.0, 3.0)

//向集中添加一个元素,同前一讲中的列表和数组不一样的是
//,Set在插入元素时并不保元素的顺序
//默认情况下,Set的实现方式是HashSet实现方式,
//集中的元素通过HashCode值进行组织
scala> numsSet+6
res20: scala.collection.mutable.Set[Double] = Set(5.0, 6.0, 3.0)

//遍历集
scala> for ( i <- res20 ) println(i)
5.0
6.0
3.0

//如果对插入的顺序有着严格的要求,则采用scala.collection.mutalbe.LinkedHashSet来实现
scala> val linkedHashSet=scala.collection.mutable.LinkedHashSet(3.0,5)
linkedHashSet: scala.collection.mutable.LinkedHashSet[Double] = Set(3.0, 5.0)

scala> linkedHashSet+6
res26: scala.collection.mutable.LinkedHashSet[Double] = Set(3.0, 5.0, 6.0)

Map操作实战

Map是一种键值对的集合,一般将其翻译为映射

//直接初始化
// ->操作符,左边是key,右边是value
scala> val studentInfo=Map("john" -> 21, "stephen" -> 22,"lucy" -> 20)
studentInfo: scala.collection.immutable.Map[String,Int] = Map(john -> 21, stephe
n -> 22, lucy -> 20)

//immutable不可变,它不具有以下操作
scala> studentInfo.clear()
<console>:10: error: value clear is not a member of scala.collection.immutable.M
ap[String,Int]
              studentInfo.clear()
                          ^
//创建可变的Map
scala> val studentInfoMutable=scala.collection.mutable.Map("john" -> 21, "stephe
n" -> 22,"lucy" -> 20)
studentInfoMutable: scala.collection.mutable.Map[String,Int] = Map(john -> 21, l
ucy -> 20, stephen -> 22)
//mutable Map可变,比如可以将其内容清空
scala> studentInfoMutable.clear()

scala> studentInfoMutable
res3: scala.collection.mutable.Map[String,Int] = Map()

//遍历操作1
scala> for( i <- studentInfoMutable ) println(i)
(john,21)
(lucy,20)
(stephen,22)

//遍历操作2
scala> studentInfoMutable.foreach(e=>
{val (k,v)=e; println(k+":"+v)}
)
john:21
lucy:20
stephen:22
//遍历操作3
scala> studentInfoMutable.foreach(e=> println(e._1+":"+e._2))
john:21
lucy:20
stephen:22

//定义一个空的Map
scala> val xMap=new scala.collection.mutable.HashMap[String,Int]()
xMap: scala.collection.mutable.HashMap[String,Int] = Map()

//往里面填充值
scala> xMap.put("spark",1)
res12: Option[Int] = None

scala> xMap
res13: scala.collection.mutable.HashMap[String,Int] = Map(spark -> 1)

//判断是否包含spark字符串
scala> xMap.contains("spark")
res14: Boolean = true

//-> 初始化Map,也可以通过 ("spark",1)这种方式实现(元组的形式)
scala> val xMap=scala.collection.mutable.Map(("spark",1),("hive",1))
xMap: scala.collection.mutable.Map[String,Int] = Map(spark -> 1, hive -> 1)

scala> "spark" -> 1
res18: (String, Int) = (spark,1)

//获取元素
scala> xMap.get("spark")
res19: Option[Int] = Some(1)

scala> xMap.get("SparkSQL")
res20: Option[Int] = None

Option,None,Some类型

Option、None、Some是scala中定义的类型,它们在scala语言中十分常用,因此这三个类型非学重要。
None、Some是Option的子类,它主要解决值为null的问题,在java语言中,对于定义好的HashMap,如果get方法中传入的键不存在,方法会返回null,在编写代码的时候对于null的这种情况通常需要特殊处理,然而在实际中经常会忘记,因此它很容易引起 NullPointerException异常。在Scala语言中通过Option、None、Some这三个类来避免这样的问题,这样做有几个好处,首先是代码可读性更强,当看到Option时,我们自然而然就知道它的值是可选的,然后变量是Option,比如Option[String]的时候,直接使用String的话,编译直接通不过。

前面我们看到:

scala> xMap.get("spark")
res19: Option[Int] = Some(1)

那要怎么才能获取到最终的结果呢,

//通过模式匹配得到最终的结果
scala> def show(x:Option[Int]) =x match{
| case Some(s) => s
| case None => “????”
| }
show: (x: Option[Int])Any

scala> show(xMap.get(“spark”))
res21: Any = 1

scala> show(xMap.get(“sparkSQL”))
res22: Any = ????

元组操作实战

前面我们提到Map是键值对的集合,元组则是不同类型值的聚集

//元组的定义
scala> ("hello","china","beijing")
res23: (String, String, String) = (hello,china,beijing)

scala> ("hello","china",1)
res24: (String, String, Int) = (hello,china,1)

scala> var tuple=("Hello","China",1)
tuple: (String, String, Int) = (Hello,China,1)

//访问元组内容
scala> tuple._1
res25: String = Hello

scala> tuple._2
res26: String = China

scala> tuple._3
res27: Int = 1

//通过模式匹配获取元组内容
scala> val (first, second, third)=tuple
first: String = Hello
second: String = China
third: Int = 1

队列操作实战

//immutable queue
scala> var queue=scala.collection.immutable.Queue(1,2,3)
queue: scala.collection.immutable.Queue[Int] = Queue(1, 2, 3)

//出队
scala> queue.dequeue
res38: (Int, scala.collection.immutable.Queue[Int]) = (1,Queue(2, 3))

//入队
scala> queue.enqueue(4)
res40: scala.collection.immutable.Queue[Int] = Queue(1, 2, 3, 4)

//mutable queue
scala> var queue=scala.collection.mutable.Queue(1,2,3,4,5)
queue: scala.collection.mutable.Queue[Int] = Queue(1, 2, 3, 4, 5)

//入队操作
scala> queue += 5
res43: scala.collection.mutable.Queue[Int] = Queue(1, 2, 3, 4, 5, 5)

//集合方式
scala> queue ++= List(6,7,8)
res45: scala.collection.mutable.Queue[Int] = Queue(1, 2, 3, 4, 5, 5, 6, 7, 8)

栈操作实战

//mutable Stack
scala> import scala.collection.mutable.Stack
import scala.collection.mutable.Stack

//new 创建方式
scala> val stack = new Stack[Int]
stack: scala.collection.mutable.Stack[Int] = Stack()

//Apply创建方式
scala> val stack1=Stack(1,2,3)
stack1: scala.collection.mutable.Stack[Int] = Stack(1, 2, 3)

//出栈
scala> stack1.top
res55: Int = 1

//入栈
scala> stack.push(1)
res57: stack.type = Stack(1)
//入栈
scala> stack.push(2)
res58: stack.type = Stack(2, 1)
//出栈
scala> stack.top
res59: Int = 2

scala> stack
res60: scala.collection.mutable.Stack[Int] = Stack(2, 1)

添加公众微信号,可以了解更多最新Spark、Scala相关技术资讯

时间: 2024-09-19 23:54:38

Scala入门到精通——第四节 Set、Map、Tuple、队列操作实战的相关文章

Scala入门到精通——第七节:类和对象(二)

本节主要内容 单例对象 伴生对象与伴生类 apply方法 应用程序对象 抽象类 单例对象 在某些应用场景下,我们可能不需要创建对象,而是想直接调用方法,但是Scala语言并不支持静态成员,Scala通过单例对象来解决该问题.单例对象的创建方式如下: object Student { private var studentNo:Int=0; def uniqueStudentNo()={ studentNo+=1 studentNo } def main(args: Array[String]):

Scala入门到精通——第五节 函数与闭包

本节主要内容 (一)函数字面量(值函数) (二)匿名函数 (三)函数的简化 (四)函数参数 (四)闭包 函数字面量(值函数) 函数字面量(function literal),也称值函数(function values),指的是函数可以赋值给变量. 一般函数具有如下形式: 而函数字面量具有如下形式: /* 函数字面量 function literal =>左侧的表示输入,右侧表示转换操作 */ scala> val increase=(x:Int)=>x+1 increase: Int =

Scala入门到精通——第二十七节 Scala操纵XML

本节主要内容 XML 字面量 XML内容提取 XML对象序列化及反序列化 XML文件读取与保存 XML模式匹配 1. XML 字面量 XML是一种非常重要的半结构化数据表示方式,目前大量的应用依赖于XML,这些应用或利用XML作为数据交换格式,或利用XML进行文件配置等.像JAVA.C++及其它流行的程序开发语言都是依赖于第三方库来实现XML的操作,例如JAVA经常通过JDOM,DOM4J等XML处理工具进行XML的操纵,但Scala提供了对XML的原生支持,通过scala.xml._包下的类或

Scala入门到精通——第十一节 Trait进阶

本节主要内容 trait构造顺序 trait与类的比较 提前定义与懒加载 trait扩展类 self type 1 trait构造顺序 在前一讲当中我们提到,对于不存在具体实现及字段的trait,它最终生成的字节码文件反编译后是等同于java中的接口,而对于存在具体实现及字段的trait,其字节码文件反编译后得到的java中的抽象类,它有着scala语言自己的实现方式.因此,对于trait它也有自己的构造器,trait的构造器由字段的初始化和其它trait体中的语句构成,下面是其代码演示: pa

Scala入门到精通——第二十一节 类型参数(三)-协变与逆变

作者:摇摆少年梦 视频地址:http://www.xuetuwuyou.com/course/12 本节主要内容 协变 逆变 类型通匹符 1. 协变 协变定义形式如:trait List[+T] {} .当类型S是类型A的子类型时,则List[S]也可以认为是List[A}的子类型,即List[S]可以泛化为List[A].也就是被参数化类型的泛化方向与参数类型的方向是一致的,所以称为协变(covariance). 图1 协变示意图 为方便大家理解,我们先分析java语言中为什么不存在协变及下一

Scala入门到精通——第二十节 类型参数(二)

本节主要内容 Ordering与Ordered特质 上下文界定(Context Bound) 多重界定 类型约束 1. Ordering与Ordered特质 在介绍上下文界定之前,我们对scala中的Ordering与Ordered之间的关联与区别进行讲解,先看Ordering.Ordered的类继承层次体系: 通过上面两个图可以看到,Ordering混入了java中的Comparator接口,而Ordered混入了java的Comparable接口,我们知道java中的Comparator是一

Scala入门到精通——第六节:类和对象(一)

本节主要内容 1 类定义.创建对象 2 主构造器 3 辅助构造器 类定义.创建对象 //采用关键字class定义 class Person { //类成员必须初始化,否则会报错 //这里定义的是一个公有成员 var name:String=null } Person类在编译后会生成Person.class文件 利用javap -prviate Person命令查看字节码文件内容,可以看得到以下内容 D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtw

Scala入门到精通——第十节 Scala类层次结构、Traits初步

本节主要内容 Scala类层次结构总览 Scala中原生类型的实现方式解析 Nothing.Null类型解析 Traits简介 Traits几种不同使用方式 1 Scala类层次结构 Scala中的类层次结构图如下: 来源:Programming in Scala 从上面的类层次结构图中可以看到,处于继承层次最顶层的是Any类,它是scala继承的根类,scala中所有的类都是它的子类 Any类中定义了下面几个方法: //==与!=被声明为final,它们不能被子类重写 final def ==

Scala入门到精通——第三十节 Scala脚本编程与结束语

本节主要内容 REPL命令行高级使用 使用Scala进行Linux脚本编程 结束语 1. REPL命令行高级使用 在使用REPL命令行时,有时候我们需要粘贴的代码比较大,而普通的粘贴可能会些一些问题,比如中文粘贴会出现乱码.多行代码粘贴时会出错,此时需要用到REPL的高级功能.在日常开发过程中,我们粘贴多行代码的时候会遇到下列问题: //本意是要粘贴下面两行代码 class Person(val name:String,val age:Int) val p=new Person("摇摆少年梦&q