官方文档 https://docs.scala-lang.org/overviews/collections/overview.html
一、集合
1.可变集合和不可变集合
不可变集合可以安全的并发访问。
可变集合可以在适当的地方被更新或扩展。这意味着你可以修改,添加,移除一个集合的元素。
# 不可变集合
scala.collection.immutable (Scala默认采用不可变集合)
# 可变集合
scala.collection.mutable
不可变集合
可变集合
2.数组
Array被隐式转换为WrappedArray(scala.collection.mutable.WrappedArray),间接拥有了集合的特征。
# Array
- 定长数组,数组不可扩容 scala.Array
- 定长数组是可变集合的一种,内容可变,但是其长度不可变
# ArrayBuffer
- 变长数组,数组可扩容 scala.collection.mutable.ArrayBuffer
- 定义数组
var arr=new Array[Int](3)
var arr=Array(1,2,3)
- 数组的一般用法
object ArrayDemo {
def main(args: Array[String]){
//初始化一个长度为8的定长数组
val arr1 = new Array[Int](8)
//会有初始化零值:Array[Int] = Array(0,0,0,0,0,0,...)
//直接打印定长数组,内容为数组的hashcode值
println(arr1)
//将数组转换成数组缓冲,就可以看到原数组中的内容了
//toBuffer会将数组转换长数组缓冲
println(arr1.toBuffer)
//注意:如果不使用new获取数组,相当于调用了数组的apply方法,直接为数组赋值
//通过一组初始化值定义定长数组
val arr2 = Array[Int](10,20,30)
//输出数组元素值
println(arr2.toBuffer)
//定义一个长度为3的定长数组
val arr3 = Array("hadoop", "storm", "spark")
//使用()来访问元素
println(arr3(2))
//包含10个整数的数组,初始化值为0
val nums = new Array[Int](10)
//遍历数组
for(i <- 0 until nums.length)
print(s"$i:${nums(i)} ") //s字符串插值
println()
//包含10个字符串的数组,初始化值为null
val strs0 = new Array[String](10)
for(i <- 0 until strs0.length)
print(s"$i:${strs0(i)} ")
println()
//赋初值的字符串数组
val strs1 = Array("hello" ,"world")
for(i <- 0 until strs1.length)
print(s"$i:${strs1(i)} ")
println()
//访问并修改元素值
strs1(0) = "byebye"
for(i <- 0 until strs1.length)
print(s"$i:${strs1(i)} ")
println()
}
}
- 数组遍历
//使用增强for循环进行数组遍历
for(elem <- nums)
println(elem)
3.元组
1.最多支持22个元素组合,分别对应类型Tuple1~Tuple22,相应也称为一元组(一般不用)、二元组、三元组...
2.元组可以容纳不同类型的元素
3.元组不可变
1.创建并元组
-二元组(map类型)
val tuplle1=("hadop",1)
-三元组
val tuple2 = (1, 3, "Fred")
val tuple3 = new Tuple3(1, 3, "Fred")
-访问元组
// 按照索引访问元组的第一个元素,从0开始
val value1 = tuple3._3
2.元组遍历
for (elem <- tuple1.productIterator) {
print(elem)
}
println()
3.Map(映射)
在Scala中,把哈希表这种数据结构叫做映射。Scala中的Map存储的内容是键值对(key-value),
Map区分可变Map (scala.collection.mutable.Map)
不可变Map(scala.collection.immutable.Map)
不可变的Map(仅TreeMap)支持有序,而可变的Map是无序的。
1.构建映射
("a",1)
"a"->1
4.List
1.列表中的元素类型必须相同。
2.列表是有序的。
3.列表是不可变的,内容及长度都不可变。
4.任何对List的修改操作都会返回新的List,而原List不会变化
1.构建
//可以使用Nil构建一个空列表 Nil=List[Nothing]
val empty = Nil
//也可以使用空元素构建一个空列表
val empty : List[Nothing] = List()
scala> val fruit = List("apples", "oranges", "pears")
fruit: List[String] = List(apples, oranges, pears)
2.遍历
/**
* List的各种遍历方式
*/
val lst = List(1,2,3,4,5);
print("foreach遍历:")
lst.foreach { x => print(x+",")} //foreach遍历,这个是传统遍历,新手不熟无奈之下可以用它
println("")
var temp = lst.map { x => x+1 } //遍历,与foreach的区别是返回值为List【B】
println("map遍历:"+temp.mkString(","));
var temp1 = lst.reduceLeft((sum,i)=>sum +i) //遍历,返回值类型是一个与集合相同的Int
println("reduce遍历返回Int:"+temp1);
var temp2 = lst.foldLeft(List[Int]())((x,y)=>y::x); //遍历,返回值是自定义类型
//ps fold类函数还可以改成 :\ ,/:的形式,代码精简了不少,但是可读性却减低了例如
println("foldLeft遍历返回自定义类型:"+temp2.mkString(","));
var temp3=( List[Int]() /: lst){(m,c)=>c::m} //遍历,实现反转
println("foldLeft遍历实现反转:"+temp2.mkString(","));
3.常用方法
//与head,tail对应的last init
scala> val abcde = List('a', 'b', 'c', 'd', 'e')
abcde: List[Char] = List(a, b, c, d, e)
scala> abcde.last
res12: Char = e
scala> abcde.init
res13: List[Char] = List(a, b, c, d)
//反转列表
scala> abcde.reverse
res14: List[Char] = List(e, d, c, b, a)
//tail,init的泛化
//提取列表的前n个元素
scala> abcde take 2
res15: List[Char] = List(a, b)
//丢弃列表的前n个元素
scala> abcde drop 2
res16: List[Char] = List(c, d, e)
scala> abcde splitAt 2
res17: (List[Char], List[Char]) = (List(a, b),List(c, d, e))
scala> List(abcde take 2, abcde drop 2)
res18: List[List[Char]] = List(List(a, b), List(c, d, e))
//拉链操作
scala> abcde zip List(1,2,3,4,5)
res22: List[(Char, Int)] = List((a,1), (b,2), (c,3), (d,4), (e,5))
4.高阶函数
如果一个函数的传入参数为函数或者返回值是函数,则该函数即为高阶函数。前面提到的集合中大部分函数都属于高阶函数:
- map、flatMap
- filter
- fold、reduce
- forall、foreach
- partition
- groupBy
- sortBy
5.闭包
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
函数体内可以方法相应作用域内的任何变量。
闭包通常来讲可以简单的认为是可以访问一个函数里面局部变量的另外一个函数。
6.柯里化
Curring函数,指的是,将原来接收两个参数的一个函数,转换为两个函数,第一个函数接收原先的第一个参数,然后返回接收原先第二个参数的第二个函数。