一、集合colletion
Scala提供了一套很好的集合实现,提供了一些集合类型的抽象。
Scala 集合分为可变的和不可变的集合。
可变集合可以在适当的地方被更新或扩展。可以修改,添加,移除一个集合的元素。
而不可变集合类,永远不会改变。不过,仍然可以模拟添加,移除或更新操作。但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变。
几种常用集合类型的应用:
序号 | 集合 | 是否可变 |
---|---|---|
1 | List(列表) List的特征是其元素以线性方式存储,集合中可以存放重复对象。 | 不可变 |
2 | Set(集合) Set是最简单的一种集合。集合中的对象不按特定的方式排序,并且没有重复对象。 | 默认不可变 |
3 | Map(映射) 把键对象和值对象映射的集合 | 默认不可变 |
4 | Tuple(元组) 不同类型的值的集合 | 不可变 |
5 | Option Option[T] 表示有可能包含值的容器,也可能不包含值。 | |
6 | Iterator(迭代器) 不是容器,更确切的说是逐一访问容器内元素的方法。 |
1 List
列表类似于数组,它们所有元素的类型都相同,但是它们也有所不同:列表是不可变的,值一旦被定义了就不能改变,其次列表 具有递归的结构(也就是链接表结构)而数组不是。
构造列表的两个基本单位是 Nil
和 ::
Nil
也可以表示为一个空列表。
def myList(): Unit = {// 空列表val empty: List[Nothing] = List() val empty = Nilval website: List[String] = List("chrome", "mooc", "w3c") // 必须有Nil,不然::报错val user = "Anna" :: ("Sarah"::Nil)val info = website ::: useruser.foreach(print)println()info.foreach(println)// 二维列表val dim: List[List[Int]] =List(List(1, 0, 0),List(0, 1, 0),List(0, 0, 1))}AnnaSarah
chrome
mooc
w3c
Anna
Sarah
1.1 列表基本操作
Scala列表有三个基本操作:
head
返回列表第一个元素
tail
返回一个列表,包含除了第一元素之外的其他元素
isEmpty
在列表为空时返回true
// info chrome,mooc,w3c,Anna,Sarah
myListFunc(info)
def myListFunc(testList:List[String]): Unit = {println(testList.head)println(testList.tail)print(testList.isEmpty)
}chrome
List(mooc, w3c, Anna, Sarah)
false
1.2 列表连接
:::
concat
1.3 List.fill()
创建指定重复数量的元素列表
def myListFill(): Unit = {val site = List.fill(3)("chrome")val num = List.fill(10)(2)println("site: " + site)println("num: " + num)
}
site: List(chrome, chrome, chrome)
num: List(2, 2, 2, 2, 2, 2, 2, 2, 2, 2)
1.4 List.tabulate()
List.tabulate() 通过给定的函数创建列表
def testListTabulate(): Unit = {val squares = List.tabulate(6)(n => n * n)println("一维: ",squares)val matrix = List.tabulate(4, 5)( _ * _ + 3)println("多维: ", matrix)
(一维: ,List(0, 1, 4, 9, 16, 25))
(多维: ,List(List(3, 3, 3, 3, 3), List(3, 4, 5, 6, 7), List(3, 5, 7, 9, 11), List(3, 6, 9, 12, 15)))
1.5 List.reverse
//info List(chrome, mooc, w3c, Anna, Sarah)
println(info.reverse)
List(Sarah, Anna, w3c, mooc, chrome)
2. Set
没有重复的对象集合,所有的元素都是唯一的
默认情况下,Scala 使用的是不可变集合,如果想使用可变集合,需要引用 scala.collection.mutable.Set 包
val set = Set(1, 2, 3, 5)
println(set.getClass.getName) // scala.collection.immutable.Set$Set4println(set.exists(_ % 2 == 0)) //true 里面有元素整除2
println(set.drop(2)) //Set(3, 5) 删除前N个元素
如果想要用可变集合,就用 scala.collection.mutable.Set 包,使用toSet可以转为不可变
def main(args: Array[String]): Unit = {val mutableSet = Set(1, 2, 3, 5)println(mutableSet.getClass.getName) // scala.collection.mutable.HashSetmutableSet.add(4) // 增加一项 Set(1, 5, 2, 3, 4)mutableSet.remove(2) // 删除元素 2mutableSet += 6 // 增加元素6 Set(1, 5, 6, 3, 4)mutableSet -= 3 // 删除元素3 Set(1, 5, 6, 4)val another = mutableSet.toSetprintln(another.getClass.getName) // scala.collection.immutable.Set 不可变}
注意: 虽然可变Set和不可变Set都有添加或删除元素的操作,但是有一个非常大的差别。
对不可变Set进行操作,会产生一个新的set,原来的set并没有改变,这与List一样。
对可变Set进行操作,改变的是该Set本身,与ListBuffer类似。
2.1 集合基本操作
Scala集合有三个基本操作:
head
返回集合第一个元素
tail
返回一个集合,包含除了第一元素之外的其他元素
isEmpty
在集合为空时返回true
2.2 连接集合
++
或者Set.++()
方法实现
def testSet()= {val site1 = Set("Edge", "Google", "Baidu") //scala.collection.immutable.Set$Set3val site2 = Set("Baidu", "Taobao")// ++ 作为运算符使用var site = site1 ++ site2println("site1 ++ site2 : " + site)// ++ 作为方法使用site = site1.++(site2)println("site1.++(site2) : " + site)
}
site1 ++ site2 : Set(Edge, Google, Baidu, Taobao)
site1.++(site2) : Set(Edge, Google, Baidu, Taobao)
2.3 查找集合中最大与最小元素
Set.min
方法查找集合中的最小元素,使用 Set.max
方法查找集合中的最大元素
def testSet()= {val num = Set(5, 6, 90, 20, 30, 45)// 查找集合中最大与最小元素println("Set(5,6,90,20,30,45) 集合中的最小元素是 : " + num.min)println("Set(5,6,90,20,30,45) 集合中的最大元素是 : " + num.max)
}Set(5, 6, 90, 20, 30, 45) 集合中的最小元素是: 5
Set(5, 6, 90, 20, 30, 45) 集合中的最大元素是: 90
2.4 交集
使用 Set.&
方法或 Set.intersect
方法来查看两个集合的交集元素
def testSet()= {val num1 = Set(5, 6, 9, 20, 30, 45) val num2 = Set(50, 60, 9, 20, 35, 55) // 交集println("num1.&(num2) : " + num1.&(num2)) // Set(20, 9)println("num1.intersect(num2) : " + num1.intersect(num2)) // Set(20, 9)
}
3 Map
可迭代的键值对(key/value)结构。Map里面的值通过键来获取。Map 中的键都是唯一的。
Map 也叫哈希表(Hash tables)
Map 有两种类型,可变与不可变,区别在于可变对象可以修改它,而不可变对象不可以。
默认情况下 Scala 使用不可变 Map。如果需要使用可变集合,需要显式的引入 import scala.collection.mutable.Map 类
在 Scala 中 可以同时使用可变与不可变 Map,不可变的直接使用 Map,可变的使用 mutable.Map。
//不可变Map
// 空哈希表,键为字符串,值为整型
var A: Map[Char, Int] = Map()
// Map 键值对演示
var colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF") // Map(red -> #FF0000, azure -> #F0FFFF)
colors += ("yellow" -> "#F000FF") // Map(red -> #FF0000, azure -> #F0FFFF, yellow -> #F000FF)
// Map基本操作
println(colors.keys) // Set(red, azure, yellow)
println(colors.values) // MapLike(#FF0000, #F0FFFF, #F000FF)
println(colors.isEmpty) // false
3.1 Map 基本操作
keys
返回 Map 所有的键(key)
values
返回 Map 所有的值(value)
isEmpty
在 Map 为空时返回true
3.2 Map合并
++
或者Map.++()
实现。
3.3 查看 Map 中是否存在指定的 Key
Map.contains
def main(args: Array[String]): Unit = {// Map 键值对演示var colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF") // Map(red -> #FF0000, azure -> #F0FFFF)colors += ("yellow" -> "#F000FF") // Map(red -> #FF0000, azure -> #F0FFFF, yellow -> #F000FF)if(colors.contains("red")){println(s"color red exists, value is", colors("red"))}else{println("color red not exists")}if (colors.contains("blue")) {println(s"color blue exists, value is", colors("blue"))} else {println("color blue not exists")}
}(color red exists, value is,#FF0000)
color blue not exists
4 Tuple
元组是不可变的,但与列表不同的是元组可以包含不同类型的元素。
def main(args: Array[String]): Unit = {val t = (1, 3.14, "Fred")println(t.getClass.getName) //scala.Tuple3val test = (1, 3.14, "Fred", 'a', 5.6, "scala", 'b', 2, 8, 9, 10, 12, 15, 18, "Fri", "Dec", 'c', 'd', 1.23, 4.56, 8.91, 99, "python", "test") // too many elements for tuple: 24, allowed: 22
}
元组的实际类型取决于它的元素的类型,目前 Scala 支持的元组最大长度为 22。对于更大长度你可以使用集合,或者扩展元组。
4.1 迭代元组
Tuple.productIterator()
def main(args: Array[String]): Unit = {val t = (1, 3.14, "Fred", 'a', 5.6)t.productIterator.foreach{i => println(i)}
}
4.2 元组转为字符串
Tuple.toString()
将元组的所有元素组合成一个字符串
4.3 元组交换元素
swap
交换元组的元素,仅限于元组内只有两个元素
def main(args: Array[String]): Unit = {val t = (1, 3.14, "Fred", 'a', 5.6, 1)val t2 = (1,2)val tString = t.toString()println(t.getClass.getName, tString.length, tString(0), tString) // (scala.Tuple5,19,(,(1,3.14,Fred,a,5.6))val tSwap = t2.swapprintln(tSwap) // (2,1)
}
5 Option
Scala Option(选项)类型用来表示一个值是可选的(有值或无值)。
Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 。
def main(args: Array[String]): Unit = {val myMap: Map[String, String] = Map("key1" -> "value")val value1: Option[String] = myMap.get("key1")val value2: Option[String] = myMap.get("key2")println(value1) // Some(value)println(value1.getOrElse().getClass.getName) // java.lang.Stringprintln(value2) // Noneprintln(value2.getOrElse().getClass.getName) // scala.runtime.BoxedUnit
}
也可以通过模式匹配来输出匹配值
def main(args: Array[String]): Unit = {val sites = Map("baidu" -> "www.baidu.com", "google" -> "www.google.com")println("show(sites.get( \"baidu\")) : " +show(sites.get("baidu")))println("show(sites.get( \"UC\")) : " +show(sites.get("UC")))
}def show(x: Option[String]) = x match {case Some(s) => scase None => "?"
}
5.1 getOrElse() 方法
使用 getOrElse()
方法来获取元组中存在的元素或者使用其默认的值
def main(args: Array[String]): Unit = {val a: Option[Int] = Some(5)val b: Option[Int] = Noneprintln("a.getOrElse(0): " + a.getOrElse(0)) // a.getOrElse(0): 5println("b.getOrElse(10): " + b.getOrElse(10)) // b.getOrElse(10): 10 println("a.isEmpty: " + a.isEmpty) // a.isEmpty: falseprintln("b.isEmpty: " + b.isEmpty) // b.isEmpty: true
}
5.2 isEmpty() 方法
使用 isEmpty()
方法检测元组中的元素是否为 None
6. Iterator
6.1 Iterator
iterator 是一种用于访问集合的方法。
迭代器 it 的两个基本操作是 next 和 hasNext。
调用 it.next()会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext()用于检测集合中是否还有元素。
def main(args: Array[String]): Unit = {val it = Iterator("Baidu", "Google", "Runoob", "Taobao")while (it.hasNext) {println(it.next())}}Baidu
Google
Runoob
Taobao
6.2 查找最大与最小元素
最大值 it.max
最小值 it.min
def main(args: Array[String]): Unit = {val ita = Iterator(20,40,2,50,69, 90)val itb = Iterator(20,40,2,50,69, 90)println("最大元素是:" + ita.max )println("最小元素是:" + itb.min )
}最大元素是:90
最小元素是:2
6.3 获取迭代器的长度
可以使用 it.size
或 it.length
方法来查看迭代器中的元素个数
def main(args: Array[String]): Unit = {val ita = Iterator(20,40,2,50,69, 90)val itb = Iterator(20,40,2,50,69, 90)println("ita.size的值:" + ita.size )println("itb的长度:" + itb.length )
}