目录
一、集合简介
(1)Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。
(2)对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本,分别位于以下两个包。
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable
(3)不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于java中的String对象
(4)可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于java中StringBuilder对象
注:Scala中的List与Java中的List是不同的概念。
二、数组
1.不可变数组
定义:val arr = new Array[Int](10)
(1)new是关键字
(2)[Int]是指定可以存放的数据类型,如果希望存放任意数据类型,则指定Any
(3)(10),表示数组的大小,确定后就不可以变化
scala中的不可变数组array是为了和java的[]数组进行对应,所以具有同样的特性,长度不可变但是内容可以修改。(本质调用伴生对象的apply方法)
def main(args: Array[String]): Unit = {
//静态定义不可变数组
val ints1: Array[Int] = Array(1,2,3,4,5)
//动态定义数组 动态构建里面的元素全部为初始值 例如int就是0
val ints2: Array[Int] = new Array[Int](6)
//修改 使用apply方法
ints2(0) = 1
//使用update方法
ints2.update(1,66)
//循环打印
for (elem <- ints2) {
println(elem)
}
//迭代器打印
val iterator: Iterator[Int] = ints2.iterator
while (iterator.hasNext){
println(iterator.next())
}
//定义函数打印方法
def myPrint(i :Int): Unit = println(i * 2 + 5)
ints2.foreach(myPrint)
ints2.foreach((i :Int) => println(i * 2 + 5))
ints2.foreach(i => println(i * 2 + 5) )
//常规方法
ints2.foreach(println)
//输出
println(ints1.toList)
println(ints2.toList)
// 因为是不可变,不会修改原数组 会在新生成的数组上改变
val ints3: Array[Int] = ints2 :+ 5
println(ints2.toList)
println(ints3.toList)
}
2.可变数组
val arr = ArrayBuffer[Any](5, 7, 9,3)
(1)[Any]存放任意数据类型
(2)(5, 7, 9,3)初始化好的四个元素
(3)ArrayBuffer需要引入scala.collection.mutable.ArrayBuffer
def main(args: Array[String]): Unit = {
//填写的数字是底层存储的初始长度 => 默认是16
//数组的长度只和里面存储元素的个数有关
val ints: ArrayBuffer[Int] = new ArrayBuffer[Int]()
//计算数组长度
val length: Int = ints.length
println(length)
//使用apply方法创建
val buffer: ArrayBuffer[Any] = ArrayBuffer(1,2,3,"ls")
buffer.foreach(println)
//添加元素
buffer.append(4)
buffer :+ 5 //:+ 即使是可变集合也加不进去元素
buffer.foreach(println)
buffer += 5 //可以加进去
buffer.foreach(println)
//可以添加多个元素
buffer.append(20, 30, 40)
println(buffer)
//在数组第一个位置添加元素
buffer.prepend(0)
println(buffer)
//数组的合并
buffer.appendAll(Array(3, 4, 5))
println(buffer)
//删除数组
buffer.remove(1, 2)
println(buffer)
// 修改查看,建议使用apply方法
println(buffer(0))
buffer.update(1, 100)
println(buffer)
buffer(1) = 200
println(buffer)
}
3.不可变数组与可变数组以及Set的转换
arr1.toBuffer //不可变数组转可变数组
arr2.toArray //可变数组转不可变数组
arr1.toSet //转化为Set集合
(1)arr2.toArray返回结果才是一个不可变数组,arr2本身没有变化
(2)arr1.toBuffer返回结果才是一个可变数组,arr1本身没有变化
// 可变数组和不可变数组的转换
val array: Array[Int] = Array(1, 2, 3, 1, 2, 3)
val arrayBuffer: ArrayBuffer[Int] = ArrayBuffer(4, 5, 6)
// 不可变数组转换为可变数组
val buffer2: mutable.Buffer[Int] = array.toBuffer
// 可变转换为不可变数组
val array1: Array[Int] = arrayBuffer.toArray
println(array.toList) //List(1, 2, 3, 1, 2, 3)
println(arrayBuffer) //ArrayBuffer(4, 5, 6)
println(buffer2) //ArrayBuffer(1, 2, 3, 1, 2, 3)
println(array1.toList) //List(4, 5, 6)
val set1: Set[Int] = array.toSet
val set2: Set[Int] = arrayBuffer.toSet
println(set1) //Set(1, 2, 3)
println(set2) //Set(4, 5, 6)
4.多维数组
创建方法:
1.val array: Array[Array[Int]] = new Array[Array[Int]](4)
2.val arrayDim: Array[Array[Int]] = Array.ofDim[Int](3, 4)
def main(args: Array[String]): Unit = {
val array: Array[Array[Int]] = new Array[Array[Int]](4)
array(0) = Array(1, 2, 3, 4)
array(1) = Array(1, 2, 3, 4)
array(2) = Array(1, 2, 3, 4)
array(3) = Array(1, 2, 3, 4)
for (elem <- array) {
for (elem01 <- elem) {
print(elem01 + "\t")
}
println()
}
val array1: Array[Array[Int]] = Array.ofDim(3, 4)
array1(0)(0) = 250
for (elem <- array1) {
for (elem01 <- elem) {
print(elem01 + "\t")
}
println()
}
}
三、Seq集合
1.不可变List
(1)List默认为不可变集合
(2)创建一个List(数据有顺序,可重复)
(3)遍历List
(4)List增加数据
(5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化
(6)取指定数据
(7)空集合Nil
操作举例:
def main(args: Array[String]): Unit = {
// List默认为不可变集合
// 创建一个List(数据有顺序,可重复)
// list无法使用new 来创建 => 因为他是一个不可变list,导致里面的元素值也不能修改
// 所以new创建出来如果都是0,不能修改,因此没法使用
val ints: List[Int] = List(1,2,3,4)
ints.foreach(println)
println(ints)
//增加数据
val ints2 = ints :+ 5
println(ints2)
//头插
val ints3: List[Int] = 6 :: ints
println(ints3)
//扁平化
val ints4: List[Int] = List(7,8,9)
val ints5: List[Any] = ints :: ints4
println(ints5) //List(List(1, 2, 3, 4), 7, 8, 9)
//扁平化类似于sql中的炸裂函数 将一个集合查分为多个单个的元素放入
val ints6: List[Int] = ints ::: ints4
println(ints6) //List(1, 2, 3, 4, 7, 8, 9)
//取元素 不可以修改元素
val i: Int = ints6(0)
println(i)
//Nil空集合
val ints7: List[Int] = 1 :: 2 :: 3 :: Nil
println(ints7)
}
2.可变ListBuffer
(1)创建一个可变集合ListBuffer
(2)向集合中添加数据
(3)删除元素
(4)查看元素
(5)修改元素
操作举例:
def main(args: Array[String]): Unit = {
val ints: ListBuffer[Int] = new ListBuffer[Int]()
val ints1: ListBuffer[Int] = ListBuffer(1,2,3,4)
//添加
ints1.append(5)
//删除
ints1.remove(1)
println(ints1)
//查看
val i: Int = ints1(1)
println(i)
//修改
ints1(2) = 250
println(ints1)
}
四、Set集合
1.不可变Set
(1)Set默认是不可变集合
(2)数据无序不可重复
(3)默认使用hashset
def main(args: Array[String]): Unit = {
val set: Set[Int] = Set(1,2,3,4,5,6,7)
//set的特性 无序 不可重复
println(set)//Set(5, 1, 6, 2, 7, 3, 4)
// 默认使用hashset,当元素小于等于4个时,会进行特殊的优化(从小到大顺序排序)
println(set.isInstanceOf[HashSet[Int]])
val ints = Set(4,5,6,4,8,9,8,1,2,4,1)
println(ints) //Set(5, 1, 6, 9, 2, 8, 4)
//添加
val ints2: Set[Int] = ints + 20
println(ints2) //Set(5, 20, 1, 6, 9, 2, 8, 4)
}
2.可变Set
创建可变集合mutable.Set
val ints = Set(4,5,6,4,8,9,8,1,2,4,1)
println(ints) //Set(5, 1, 6, 9, 2, 8, 4)
//添加
val ints2: Set[Int] = ints + 20
println(ints2) //Set(5, 20, 1, 6, 9, 2, 8, 4)
val ints3: mutable.Set[Int] = mutable.Set(2,5,7,6,2,3,1,1)
println(ints3)
// 可变set能够添加元素,添加的元素一样没有顺序
ints3.add(20)
println(ints3)
val bool: Boolean = ints3.add(30) //true 不存在30 可添加
println(bool)
// 判断set中是否存在元素
val bool1: Boolean = ints3.contains(30)
println(bool1)
五、Map集合
Scala中的Map也是一个散列表,存储的内容也是键值对(key-value)映射
1.不可变集合
def main(args: Array[String]): Unit = {
val map1: Map[String, Int] = Map("hi" -> 1,"hello" -> 2)
println(map1)
val map2: Map[String, Int] = Map(("hi",1),("hello",2))
println(map2)
// 不可变map内容不能修改,也不能添加元素,只可以读取
for (elem <- map2) {
val key: String = elem._1
val value: Int = elem._2
println("key:" + key + "\t" + "value:" + value)
}
val keys: Iterable[String] = map2.keys
val values: Iterable[Int] = map2.values
println(keys.toList)
println(values.toList)
// 通过key获取value
// 避免空值异常 如果获取的key不存在 value为任意类型 可以为数值类型
// 数值类型不能使用null值表示 需要使用Option表示
// option用于封装数据 代替null值, 如果数值存在 使用some子类表示 如果不存在使用None表示
val option: Option[Int] = map2.get("hello01")
println(option) //None
if(!option.isEmpty){
val value1 :Int = option.get
println(value1)
}
//使用ption优化的方法
val i: Int = option.getOrElse(10) //如果没有 就返回10
println(i)
val j: Int = map2.get("hello").getOrElse(10)
println(j)
// 如果有值 获取值作为返回结果 如果没有值 使用第二个参数作为默认值
val i1: Int = map2.getOrElse("hello",0)
println(i1)
//使用apply方法读取
val i2: Int = map2("hello")
println(i2)
}
2.可变集合
val map3: mutable.HashMap[String, Int] = new mutable.HashMap[String,Int]()
val map4: mutable.Map[String, Int] = mutable.Map(("hi",1),("hello",2))
//添加
//如果存在会修改value值 如果不存在会添加元素
map4.update("nihao",3)
println(map4)
map4.put("nihao",5)
println(map4)
//使用apply
map4("nihao") = 100
println(map4)
//删除
map4.remove("nihao")
println(map4)
六、元组
元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。
注意:元组中最大只能有22个元素。
Map中的键值对其实就是元组,只不过元组的元素个数为2,称之为对偶
def main(args: Array[String]): Unit = {
val list: List[Any] = List(1,3.14,"l s")
// 如果list存放的数据类型不一致,那么里面的类型会被标记为共同的父类
// 导致每个元素自身的类型丢失
val unit: Any = list(2)
println(unit)
// 如果需要对string进行操作 需要自己完成类型转换
if(unit.isInstanceOf[String]){
val str: String = unit.asInstanceOf[String]
val strings: Array[String] = str.split(" ")
println(strings.toList)
}
// 引入元组来保存不同类型的数据,能够记录下每个位置元素的类型
val tuple: (String, Int) = new Tuple2[String,Int]("hi",1)
val key: String = tuple._1
val value: Int = tuple._2
// tuple在创建的时候,直接使用()来表示
val tuple01: (String, Int) = ("hi",1)
//创建map时 可以用二元组来表示
val map: Map[String, Int] = Map(("hi",1),("nihao",2))
for (elem <- map) {
val key01: String = elem._1
val value01: Int = elem._2
}
//map与list转换
val list1: List[(String, Int)] = map.toList
println(list1)
//打印
list1.foreach((tuple:(String,Int)) =>println(tuple._1 + "\t" + tuple._2))
}
七、队列
Scala也提供了队列(Queue)的数据结构,队列的特点就是先进先出。进队和出队的方法分别为enqueue和dequeue。
def main(args: Array[String]): Unit = {
val queue: Queue[Int] = Queue(1,2,3,4)
// 不可变队列即使调用进队的方法 也没有办法将数据加入到队列中 必须创建新对象
val queue1: Queue[Int] = queue.enqueue(5)
println(queue)
println(queue1)
// 返回值需要保留两个数据 所以设计成了二元组
// (数据,弹出之后剩下的队列)
val dequeue: (Int, Queue[Int]) = queue.dequeue
println(dequeue) //(1,Queue(2, 3, 4))
val queue2: mutable.Queue[Int] = new mutable.Queue[Int]()
queue2.enqueue(1,2,3)
println(queue2)
val i: Int = queue2.dequeue()
println(i) //1
println(queue2) //Queue(2, 3)
}
八、并行集合
Scala为了充分使用多核CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。
def main(args: Array[String]): Unit = {
// 单线程运行
// 常规写的代码都是单线程的 在main线程中 有序
val inclusive: Range.Inclusive = 1 to 100
//inclusive.foreach((i:Int ) => println(i+ Thread.currentThread().getName))
// 使用并行集合
// 会开启多个线程完成任务 造成乱序 只在单个线程中是有序的
inclusive.par.foreach((i:Int ) => println(i+Thread.currentThread().getName))
}