数据结构特点
Scala同时支持可变集合和不可变集合,不可变集合从不可变,可以安全的并发访问。
两个主要的包:
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable
Scala优先采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本。
数组
定义定长数组
我们可以定义一个固定长度大小和类型的定长数组
//定义一个数组长度为10,类型为Int的固定大小数组
val array = new Array[Int](10)
array(1) = 10
array(2) = 20
//访问数组当中的某一个下标元素值
println(array(1))
//直接使用apply方法进行生成一个数组
val array2 = Array(1,2,3)
//访问数组的元素
println(array2(2))
变长数组
我们也可以通过ArrayBuffer来定义一个变长数组
val array3 = new ArrayBuffer[Int]()
array3.append(20)
val array4 = ArrayBuffer[String]()
array4.append("helloworld")
定长数组与变长数组的相互转换
定长数组转换成变长数组
//定长数组转换成变长数组
val toBuffer = array.toBuffer
toBuffer.append(50)
变长数组转换为定长数组
//变长数组准换成定长数组
val toArray = array3.toArray
多维数组
我们可以通过Array的ofDim方法来定义一个多维的数组,多少行,多少列,都是我们自己定义说了算
val dim = Array.ofDim[Double](3,4)
dim(1)(1) = 11.11
println(dim.mkString(","))
scala当中数组的遍历
val array5 = ArrayBuffer(1,2,3,4,5,6)
for(x <- array5){
println(x )
}
数组的常见算法
val array6 = Array(1,2,3,4,5,6)
//求和
array6.sum
//求最大值
array6.max
//排序
array6.sorted
元组tuple
在scala当中提供元组tuple的数据类型,可以理解tuple为一个容器,可以存放各种不同的数据类型的数据,例如一个Tuple当中既可以存放String类型数据,同时也可以存放Int类型的数据
注意:注意元组一旦创建之后,就是不可变的,也就是说元组当中没有添加和删除元素这一说
创建元组
创建元组,直接使用小括号,小括号当中存放我们元组当中各种类型的元素即可
val tuple1 = ("hello",1,5.0f)
println(tuple1)
2、元组数据的访问
访问元组当中的数据直接使用_加角标即可,但是要注意,元组当中的数据角标是从1开始的
val tuple1 = ("hello",1,5.0f)
println(tuple1)
val tuple1Result = tuple1._1
println(tuple1Result)
3、元组的遍历
val tuple1 = ("hello",1,5.0f)
println(tuple1)
val tuple1Result = tuple1._1
println(tuple1Result)
//第一种方式遍历元组
for(x <- tuple1.productIterator){
println(x)
}
//第二种方式遍历元组
tuple1.productIterator.foreach( x => println(x))
映射Map
scala当中的Map集合与java当中的Map类似,也是key,value对形式的
不可变映射
val map1 = Map("hello" ->"world","name" -> "zhangsan","age" -> 18)
可变映射及其操作
val map2 = scala.collection.mutable.Map("hello" ->"world","name" -> "zhangsan","age" -> 18)
//可变map添加元素
map2.+=("address" ->"地球")
println(map2)
//可变map删除元素.注意,删除元素是返回一个删除元素之后的map,原来的map并没有改变
val map3 = map2.-("address")
println(map2)
println(map3)
//或者使用覆盖key的方式来更细元素
map2 += ("address" -> "北京")
println(map2)
//或者使用 + 来进行更新元素
//注意,map当中没有phonNo这个key,则不能更细
map2 +("address" ->"上海","phonNo" -> "13688886666")
println(map2)
获取map当中指定的key值
//通过key来进行取值
map2.get("address")
//通过key来进行取值,如果没有这个key,就用后面给定的默认值
map2.getOrElse("address","非洲")
//通过key来进行取值,真的没有这个key,那么就用后面给定的默认值
map2.getOrElse("phoNo","13133335555")
遍历Map当中的元素
//遍历key与value
for((k,v) <- map2){
println(k)
println(v)
}
//遍历获取所有的key
for(k <- map2.keys) {
println(k)
}
//遍历获取所有的value
for(v <- map2.values) {
println(v)
}
//打印key,value对
for(kv <- map2){
println(kv)
}
将对偶的数组转变为map
//将对偶的元组转变为map
val arrayMap = Array(("name","zhangsan"),("age",28))
val toMap = arrayMap.toMap
println(toMap)
列表(List)
scala当中也提供有与java类似的List集合操作
创建列表
注意:列表当中的元素类型可以是不同的,这一点与我们元组类似,但是列表当中的元素是可以删减的
val list1 = List("hello",20,5.0f)
println(list1)
访问列表当中的元素
//访问列表当中的元素
val list1Result = list1(0)
println(list1Result)
列表当中添加元素
我们可以从列表头部或者尾部添加元素
val list2 = list1:+50
val list3 = 100+:list1
println(list2)
println(list3)
List的创建与追加元素
Nil是一个空的List,定义为List[Nothing]
//尾部添加了Nil,那么就会出现List集合里面装List集合的现象
val list4 = 1::2 ::3 :: list1 ::Nil
println(list4)
//尾部没有添加Nil的值,那么所有的元素都压平到一个集合里面去了
val list5 = 1::2::3::list1
println(list5)
变长List的创建与使用
val list6 = new ListBuffer[String]
list6.append("hello")
list6.append("world")
println(list6.mkString(","))
val list7 = list6.toList
println(list7)
Set集合
集是不重复元素的结合。集不保留顺序,默认是以哈希集实现。
如果想要按照已排序的顺序来访问集中的元素,可以使用SortedSet(已排序数据集),已排序的数据集是用红黑树实现的。
默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包。
不可变集合的创建
val set1 =Set("1","1","2","3")
println(set1.mkString(","))
可变集合的创建以及添加元素
如果我们引入的集合的包是可变的,那么我们创建的集合就是可变的
import scala.collection.mutable.Set
val set2 = Set(1, 2, 3)
set2.add(4)
set2 += 5
//使用.这个方法添加元素,会返回一个新的集合
val set3 = set2.+(6)
println(set2.mkString(","))
println(set3.mkString("\001"))
可变集合删除元素
set3 -= 1
println(set3.mkString("."))
set3.remove(2)
println(set3.mkString("."))
遍历Set集合元素
for(x <- set3){
println(x )
}
Set更多常用操作介绍
集合元素与函数的映射
我们可以使用map方法,传入一个函数,然后将这个函数作用在集合当中的每一个元素上面
map:将集合中的每一个元素映射到某一个函数
val listFunc = List("name","age","zhangsan","lisi")
println(listFunc.map(x => x +"hello"))
println(listFunc.map(_.toUpperCase()))
flatmap:flat即压扁,压平,扁平化,效果就是将集合中的每个元素的子元素映射到某个函数并返回新的集合
val listFunc2 = List("address","phonNo")
println(listFunc2.flatMap( x => x +"WORLD"))
队列Queue
队列Queue是一个先进先出的结构
创建队列
//创建可变的队列
val queue1 = new mutable.Queue[Int]()
println(queue1)
队列当中添加元素
//队列当中添加元素
queue1 += 1
//队列当中添加List
queue1 ++=List(2,3,4)
println(queue1)
按照进入队列顺序,删除队列当中的元素(弹出队列)
val dequeue = queue1.dequeue()
println(dequeue)
println(queue1)
向队列当中加入元素(入队列操作)
//塞入元素到队列
queue1.enqueue(5,6,7)
println(queue1)
获取第一个与最后一个元素
//获取第一个元素
println(queue1.head)
//获取最后一个元素
println(queue1.last)
集合当中的化简、折叠与扫描操作
折叠、化简 reduce操作
将二元函数引用集合当中的函数
val reduceList = List(1,2,3,4,5)
//1-2-3-4-5 = -13
val reduceLeftList = reduceList.reduceLeft(_ - _)
val reduceLeftList2 = reduceList.reduceLeft((x,y) => x-y)
println(reduceLeftList)
println(reduceLeftList2)
//reduceRight操作
// 4-5 = -1
// 3- (-1) = 4
//2-4 = -2
//1 -(-2) = 3
val reduceRightList = reduceList.reduceRight(_ - _)
println(reduceRightList)
折叠、化简folder操作
fold函数将上一步返回的值作为函数的第一个参数继续传递参与运算,直到list中的所有元素被遍历。可以把reduceLeft看做简化版的foldLeft。相关函数:fold,foldLeft,foldRight,可以参考reduce的相关方法理解。
reduce的本质其实就是fold操作,只不过我们使用fold操作的时候,需要指定初始值
fold操作
val foldList = List(1,9,2,8)
val foldResult = foldList.fold(10)((x,y) => x+y)
println(foldResult)
foldLeft操作
//50-1-9-2-8 = 30
val foldLeftResult = foldList.foldLeft(50)((x,y) => x-y)
println(foldLeftResult)
拉链操作
对于多个List集合,我们可以使用Zip操作,将多个集合当中的值绑定到一起去
val zipList1 = List("name","age","sex")
val zipList2 = List("zhangsan",28)
val zip = zipList1.zip(zipList2)
val toMap1 = zip.toMap
println(zip)
println(toMap1)
迭代器
对于集合当中的元素,我们也可以使用迭代器来进行遍历
val listIterator = List(1,2,"zhangsan")
val iterator = listIterator.iterator
while(iterator.hasNext){
println(iterator.next())
}