集合
集合简介
Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。
对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本,分别位于以下两个包:
- 不可变集合:scala.collection.immutable
- 不可变集合:scala.collection.mutable
不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于Java中的String对象。
可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于Java中的StringBuidler对象。
数组
不可变数组
val arr1 = new Array[Int](10)
[Int] 是指定可以存放的数据类型,如果希望为任意类型,则可以指定为Any
(10) 表示数组的大小,确定后不可以变化
package chapter07
object Test01_ImmutableArray {
def main(args: Array[String]): Unit = {
// 1. 创建数组
val arr = new Array[Int](10)
// 另一种创建方式
val arr2 = Array(12, 37, 42, 58, 97)
// 2. 访问数组中的元素
println(arr(0))
// println(arr(5))
// 赋值
arr(0) = 12
arr(1) = 24
println(arr(0))
// TODO 数组的遍历
// 普通for循环
for(i <- 0 to arr.length - 1) {
println(arr(i))
}
for (i <- arr.indices) println(arr(i))
// 直接遍历所有元素,增强for循环
for(elem <- arr2) {
println(elem)
}
// 迭代器
val iter = arr.iterator
while (iter.hasNext)
println(iter.next())
// 调用foreach方法
arr2.foreach((elem: Int) => println(elem))
arr2.foreach(println) // 至简原则
// 以字符串输出
println(arr2.mkString("--"))
}
}
可变数组
package chapter07
import scala.collection.mutable.ArrayBuffer
object Test02_ArrayBuffer {
def main(args: Array[String]): Unit = {
// TODO 创建可变数组
// 默认长度为16
val arr = new ArrayBuffer[Int]()
val arr2 = ArrayBuffer(25, 37, 98)
println(arr.mkString(", "))
// 重写了toString方法,可以直接打印
println(arr2)
// 访问元素
// println(arr(0)) // 此时数组越界
println(arr2(1))
// arr(0) = 5
// println(arr(0))
// TODO 添加元素
arr += 19
77 +=: arr
arr.append(36)
arr.prepend(52, 34)
// 索引位置和数据
arr.insert(2, 32, 59)
println(arr)
// TODO 删除元素
// 索引位置
arr.remove(2)
// 索引位置 删除个数
arr.remove(2, 3)
// 删除元素的Value,如果找不到什么都不做
arr -= 36
println(arr)
}
}
可变数组与不可变数组的转换
// 可变数组转换为不可变数组
val arr:ArrayBuffer[Int] = ArrayBuffer(23, 56, 98)
var array: Array[Int] = arr.toArray
// 不可变数组转换为可变数组
val arrayBuffer = array.toBuffer
多维数组
package chapter07
object Test03_MulArray {
def main(args: Array[String]): Unit = {
// TODO 创建二维数组
val array = Array.ofDim[Int](2, 3)
// 访问元素
array(0)(2) = 19
array(1)(0) = 25
// 遍历
for(i <- 0 until array.length; j <- 0 until array(i).length) {
println(array(i)(j))
}
for (i <- array.indices; j <- array(i).indices) {
print(array(i)(j) + "\t")
if (j == array(i).length-1)
println()
}
array.foreach(line => line.foreach(println))
}
}
列表
不可变List
List默认为不可变集合
创建一个List(数据有顺序,可重复)
遍历List
List增加数据
集合间合并:将一个整体拆分成一个一个的个体,成为扁平化
去指定数据
空集合Nil
package chapter07
import scala.+:
object Test04_List {
def main(args: Array[String]): Unit = {
// TODO 创建List
// 通过List伴生对象的apply方法创建
val list = List(23, 65, 87)
// TODO 访问元素
println(list(1))
list.foreach(item => println(item))
// TODO 添加元素
val newList = list :+ 10
val newList2 = 10 +: list
println(newList)
println(newList2)
println("=======================")
val newList3 = list.::(51)
// 通常上述的这种操作的使用场景
// 我们可以在一个空集合后面添加元素
val list2 = Nil.::(13)
// 但是这样使用看上去还是没什么用
// 所以有了下边的方式,将想要的数字生成一个列表
val list3 = 13 :: Nil
val list4 = 14 :: 53 :: -32 :: Nil
// TODO 合并列表
// 扁平化处理
val list5 = list ::: list4
println(list5)
val list6 = list ++ list4
println(list6)
}
}
可变
package chapter07
import scala.collection.mutable.ListBuffer
object Test05_ListBuffer {
def main(args: Array[String]): Unit = {
// TODO 创建可变列表
val list: ListBuffer[Int] = new ListBuffer[Int]()
val list2 = ListBuffer(12, 53, 75)
println(list)
println(list2)
// TODO 添加元素
list.append(15, 62)
println("list =>" + list)
list2.prepend(32, 25, 64)
println("list2 => " + list2)
// 指定位置添加
list.insert(19, 22)
println("list =>" + list)
// list += 32 += 21
31 +=: 16 +=: list += 32 += 21
println("list => " + list)
// 合并List
val list3 = list ++ list2
println("list3 => " + list3)
list ++= list2
println(list)
// TODO 修改元素
list2(2) = 80
list2.update(0, 30)
println(list2)
// TODO 删除元素
list2.remove(2)
list2 -= 25
println(list2)
}
}
Set集合
默认情况下,Scala使用的是不可变集合。如果你想使用可变集合,需要引用scala.collection.mutable.Set包
不可变Set
Set默认是不可变集合,数据无序
数据不可重复
遍历集合
package chapter07
object Test06_ImmutableSet {
def main(args: Array[String]): Unit = {
// TODO 创建Set
println("----------创建Set----------")
val set = Set(13, 23, 53, 12, 13, 23, 78)
println("set => " + set)
// TODO 添加元素
println("----------添加元素----------")
val set2 = set.+(20)
val set3 = set + 30
println("set2 => " + set2)
println("set3 => " + set3)
// TODO 合并集合
// 相同的数据会进行去重,不同的数据保存
println("----------合并Set----------")
val set4 = Set(19, 13, 23, 53, 67, 99)
val set5 = set ++ set4
println("set5 => " + set5)
// TODO 删除元素
println("----------删除元素----------")
val set6 = set -12
println("set6 => " + set6)
}
}
可变Set
package chapter07
import scala.collection.mutable.Set
object Test07_MutableSet {
def main(args: Array[String]): Unit = {
// TODO 创建Set
println("----------创建Set----------")
val set: Set[Int] = Set[Int](13,23,53,12,13,23,78)
println("set => " + set)
// TODO 添加元素
println("----------添加元素----------")
set += 11
println("set => " + set)
val flag = set.add(20)
println("set => " + set)
println("flag =>" + flag)
// TODO 删除元素
println("----------删除元素----------")
set -= 13
println("set => " + set)
val removeFlag = set.remove(2)
println("set => " + set)
println("removeFlag => " + removeFlag)
// TODO 合并Set
println("----------合并Set----------")
val set2 = Set(13, 12, 13, 27, 28, 29)
val set3 = set ++ set2
println("set =>" + set)
println("set2 => " + set2)
println("set3 => " + set3)
set ++= set2
println("set =>" + set)
println("set2 => " + set2)
}
}
Map集合
Scala中的Map和Java类似,也是一个散列表,他存储的内容也是键值对映射
不可变Map
不可变的Map集合中不可以增加元素。
package chapter07
object Test08_ImmutableMap {
def main(args: Array[String]): Unit = {
// TODO 创建Map
println("----------创建Map----------")
val map: Map[String, Int] = Map("Hello" -> 4, "World" -> 2)
println(map)
println(map.getClass)
// TODO 遍历元素
println("----------遍历元素----------")
map.foreach(println)
map.foreach((kv: (String, Int)) => println(kv))
// TODO 取map中所有的key和value
println("----------取map中所有的key和value----------")
for (key <- map.keys) {
println(s"${key} ---> ${map.get(key).get}")
}
// TODO 访问某一个key的value
println(map.get("Hello").get)
// 推荐写法
println(map.getOrElse("World", 0))
println(map.getOrElse("Nothing", 0))
}
}
可变Map
package chapter07
import scala.collection.mutable.Map
object Test09_MutableMap {
def main(args: Array[String]): Unit = {
val map:Map[String, Int] = Map("Hello" -> 4, "World" -> 2)
// TODO 添加元素
println("----------添加元素----------")
map.put("Scala", 2)
println(map)
// 使用符号添加
map += (("Spark", 3))
println(map)
// TODO 删除元素
println("----------删除元素----------")
map.remove("Hello")
map -= "Spark"
println(map)
// TODO 修改元素
println("----------修改元素----------")
map.update("Scala", 3)
println(map)
// TODO 合并两个Map
println("----------合并两个Map----------")
val map2 = Map[String, Int]("Hello" -> 20, "aaa" -> 32)
map ++= map2
// map2会覆盖map中重复的值
println(map)
}
}
元组
元组也是可以理解为一个容器,可以存放各种相同或者不同类库的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。
元组最大只能有22个元素。
package chapter07
object Test10_Tuple {
def main(args: Array[String]): Unit = {
// TODO 创建元组
val tuple: (String, Int, Char, Boolean) = ("hello", 100, 'a', true)
println(tuple)
// TODO 访问数据
println(tuple._1)
println(tuple._2)
println(tuple.productElement(2))
// TODO 遍历元组数据
for (elem <- tuple.productIterator) {
println(elem)
}
// TODO 嵌套元组
val mulTuple = (12, 0.3, "hello", ("haha", "scala", 23), true)
println(mulTuple._4._1)
}
}
集合常用函数
基本属性和常用操作
package chapter07
object Test11_CommonOperation {
def main(args: Array[String]): Unit = {
val list = List(1,3,5,7,2,89,100)
val set = Set(23,34,423,75)
// 获取集合长度
println(list.length)
// 获取集合大小
println(list.size)
println(set.size)
// 循环遍历
for(elem <- list) {
print(elem + "\t")
}
println()
for (elem <- set) {
print(elem + "\t")
}
println()
// 迭代器
for (elem <- set.iterator) print(elem + "\t")
println()
// 生成字符串
println(list)
// 是否包含
println(list.contains(23))
}
}
衍生集合
package chapter07
object Test12_DerivedCollection {
def main(args: Array[String]): Unit = {
val list = List(1,3,5,7,2,89,100)
val list2 = List(3, 89, 32, 6, 5, 2)
println(list)
// 获取集合的第一个元素
println(list.head)
// 获取除了集合第一个元素外所有的元素
println(list.tail)
// 集合初始数据(不包含最后一个)
println(list.init)
// 获取集合的最后一个元素
println(list.last)
// 反转
println(list.reverse)
// 取前(后)n个元素
println(list.take(3))
println(list.takeRight(3))
// 去掉前(后)n个元素
println(list.drop(3))
println(list.dropRight(1))
// 并集
val union = list.union(list2)
println("union =>" + union)
println(list:::list2)
// 如果是set做并集,则会去重
// 交集
val intersection = list.intersect(list2)
println("intersection =>" + intersection)
// 差集
val diff1 = list.diff(list2)
val diff2 = list.diff(list)
println("diff1 => " + diff1)
println("diff2 => " + diff2)
// 拉链
println("zip => " + list.zip(list2))
println("--------------------")
// 滑窗
for (elem <- list.sliding(3)) {
println(elem)
}
println("--------------------")
for(elem <- list2.sliding(3, 2))
println(elem)
}
}
集合计算初级函数
package chapter07
object Test13_SimpleFunction {
def main(args: Array[String]): Unit = {
val list= List(5,1,8,2,-3,4)
val list2 = List(("a", 3), ("b", 5), ("c", 9), ("d", 2), ("e", 6))
// 求和
val sum = list.sum
println(sum)
// 求乘积
println(list.product)
// 最大值
println(list.max)
println(list2.maxBy((tuple: (String, Int)) => tuple._2))
// 简化
println(list2.maxBy(_._2))
// 最小值
println(list.min)
println(list2.minBy(_._2))
// 排序
val sortedList = list.sorted
println(sortedList)
// 从大到小逆序排列
// 传入一个隐式参数
val sortedListDesc = list.sorted(Ordering[Int].reverse)
println(sortedListDesc)
println(list2.sortBy((tuple:(String, Int)) => tuple._2)(Ordering[Int].reverse))
// sortWith
println(list.sortWith((a: Int, b: Int) => { a < b }))
// 简化
println(list.sortWith(_ < _))
println(list.sortWith(_ > _))
}
}
集合计算高级函数
package chapter07
object Test14_HighLevelFunction_Map {
def main(args: Array[String]): Unit = {
val list = List(1,2,3,4,5,6,7)
// TODO 过滤
// 选取偶数
list.filter( (elem:Int) => {elem % 2 == 0} )
println(list.filter(_%2==0))
// TODO 转化映射map
// 把集合每个数*2
list.map((elem: Int) => {elem * 2})
// TODO 扁平化
val nestedList: List[List[Int]] = List(List(1,23,5), List(6,7,8,9), List(4,5))
println(nestedList.flatten)
// 扁平映射
// 将一组字符串进行分词,并保存成单词的列表
val strings: List[String] = List("Hello world", "Hello Scala", "Hello Java")
// 1.分词
val splitList: List[Array[String]] = strings.map(string => { string.split(" ")})
println(splitList)
// 扁平化
val flattenList = splitList.flatten
println(flattenList)
// 这样的步骤看着有点复杂,所以引出我们的扁平化操作
val flattenMapList = strings.flatMap(_.split(" "))
println(flattenMapList)
// TODO 分组操作
// 分成奇偶两组
val groupMap = list.groupBy( _ % 2 == 0 )
val groupMap2 = list.groupBy(data => if (data % 2 == 0) "偶数" else "奇数" )
}
}
package chapter07
object Test15_HighLevelFunction_Reduce {
def main(args: Array[String]): Unit = {
val list= List(1,2,3,4,5)
// 归约
// reduce
println(list.reduce( _ + _ ))
println(list.reduceRight(_ - _)) // 1 - ( 2 - ( 3 - ( 4 - 5) ) )
// fold
println(list.fold(10)( _ + _))
println(list.foldRight(10)( _ - _ )) // 1 - ( 2 -( 3 - ( 4 - (5 - 10) ) ))
}
}