第7章 集合
7.1 简介
Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本。
可变集合可以在适当的地方被更新或扩展。这意味着你可以修改,添加,移除一个集合的元素。而不可变集合类,相比之下,永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变,所以这里的不可变并不是变量本身的值不可变,而是变量指向的那个内存地址不可变
可变集合和不可变集合,在scala中该如何进行区分呢?我们一般可以根据集合所在包名进行区分:
- scala.collection.immutable
- scala.collection.mutable
7.2 数组
object Scala01_Collection {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 数组
// 数组 :严格意义上,数组不是集合
// scala中给数组一个特定的类型:Array
// 构建Scala中的数组,其实等同于构造Java的数组
val array = new Array[String](3)
println(array)
// 访问
// 可以根据索引访问数组的元素
//array.update(1, "abc")
// 中括号在scala中表示泛型,所以不能在索引操作中使用,使用小括号
array(1) = "abc"
// 遍历
for ( i <- array ) {
println(i)
}
}
}
object Scala01_Collection_1 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 数组
// 集合分为两大类:可变集合,不可变集合
// Scala默认提供的集合都是不可变。
val array = new Array[String](3)
array(0) = "a"
array(1) = "a"
array(2) = "a"
// 使用集合的伴生对象构建集合,并同时初始化
val array1 = Array(1,2,3,4)
val array2 = Array(5,6,7,8)
//val array2 = Array.apply(1,2,3,4)
// 访问
//val ints: Array[Int] = array1.+:(5)
// scala中如果运算符是以冒号结尾,那么运算规则为从后向前计算
val ints = 5 +: array1
//val ints1: Array[Int] = array1.:+(5)
val ints1 = array1 :+ 5
val ints2 = array1 ++ array2
val ints3 = array1 ++: array2
//println(array1 eq ints)
//println(array1 eq ints1)
// println(ints eq ints1)
// TODO 遍历
//println(ints.mkString(","))
//println(ints1.mkString(","))
//println(ints2.mkString(","))
// foreach方法是一个循环的方法,需要传递一个参数,这个从参数的类型是函数类型
// 函数类型 : Int => U
def foreachFunction(num:Int): Unit = {
println(num)
}
//array1.foreach(foreachFunction)
//array1.foreach((num:Int)=>{println(num)})
//array1.foreach((num:Int)=>println(num))
//array1.foreach((num)=>println(num))
//array1.foreach(num=>println(num))
array1.foreach(println(_))
}
}
7.2.1 不可变数组
- 基本语法
object ScalaCollection{
def main(args: Array[String]): Unit = {
//(1)数组定义
val arr01 = new Array[Int](4)
println(arr01.length) // 4
//(2)数组赋值
//(2.1)修改某个元素的值
arr01(3) = 10
val i = 10
arr01(i/3) = 20
//(2.2)采用方法的形式修改数组的值
arr01.update(0,1)
//(3)遍历数组
//(3.1)查看数组
println(arr01.mkString(","))
//(3.2)普通遍历
for (i <- arr01) {
println(i)
}
//(3.3)简化遍历
def printx(elem:Int): Unit = {
println(elem)
}
arr01.foreach(printx)
arr01.foreach((x)=>{println(x)})
arr01.foreach(println(_))
arr01.foreach(println)
}
}
- 基本操作
object Scala01_Collection_2 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 数组
// 多维数组
var myMatrix = Array.ofDim[Int](3,3)
//myMatrix.foreach(list=>println(list.mkString(",")))
val arr1 = Array(1,2,3,4)
val arr2 = Array(5,6,7,8)
// 合并数组
val arr6: Array[Int] = Array.concat(arr1, arr2)
//arr6.foreach(println)
// 创建指定范围的数组
val arr7: Array[Int] = Array.range(0,2)
//arr7.foreach(println)
val arr8:Array[Int] = Array.fill[Int](5)(-1)
arr8.foreach(println)
}
}
7.2.2 可变数组
- 基本语法
object Scala02_Collection {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 数组 - 可变数组
//val buffer = new ArrayBuffer[String]()
val buffer = ArrayBuffer("a", "b", "c")
println(buffer)
// TODO 操作
//buffer.append("a", "b", "c", "d")
// buffer.appendAll(Array("a", "b", "c"))
//buffer.insert(100, "f")
//buffer.update(0, "e")
//buffer(0) = "e"
//buffer.remove(2)
//buffer.remove(2,2)
val strings: ArrayBuffer[String] = buffer - "a"
println(buffer eq strings)
println(buffer)
println(strings)
}
}
- 基本操作
import scala.collection.mutable.ArrayBuffer
object ScalaCollection{
def main(args: Array[String]): Unit = {
val buffer1 = ArrayBuffer(1,2,3,4)
val buffer2 = ArrayBuffer(5,6,7,8)
val buffer3: ArrayBuffer[Int] = buffer1 += 5
println( buffer1 eq buffer3 ) // true
// 使用 ++ 运算符会产生新的集合数组
val buffer4: ArrayBuffer[Int] = buffer1 ++ buffer2
// 使用 ++= 运算符会更新之前的集合,不会产生新的数组
val buffer5: ArrayBuffer[Int] = buffer1 ++= buffer2
println( buffer1 eq buffer4 ) // false
println( buffer1 eq buffer5 ) // true
}
}
7.2.3 可变数组和不可变数组转换
object Scala02_Collection_2 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 数组 - 可变数组
val array = Array(1,2,3,4)
// 不可变 => 可变
val buffer: mutable.Buffer[Int] = array.toBuffer
val buff = ArrayBuffer(1,2,3,4)
// 可变 => 不可变
val array1: Array[Int] = buff.toArray
// Java集合 <=> Scala集合
array1.foreach(println)
import scala.collection.JavaConverters._
//val list = new java.util.ArrayList()
//list.asScala.foreach(println)
val java: util.List[Int] = List(1, 2, 3, 4).asJava
}
}
7.2.4 数组方法详解
object Scala03_Collection {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 方法
val array = Array(1,2,3,4)
println(array.size)
println(array.length)
println(array.isEmpty)
println(array.contains(2))
println(array.distinct.mkString(","))
println(array.reverse.mkString(","))
println(array.mkString(","))
array.foreach(println)
array.iterator
}
}
import scala.collection.mutable.ArrayBuffer
object Scala03_Collection_1 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 方法
val array = ArrayBuffer(1,2,3,4)
// 从集合中获取部分数据
println(array.head)
println(array.tail)
println(array.tails)
println(array.last)
println(array.init) // 初始
println(array.inits)
// 取前几个
println(array.take(3))
//println(array.reverse.take(2).reverse)
println(array.takeRight(2))
println(array.drop(1))
println(array.dropRight(1))
}
}
7.2.5 重要的函数
flatMap
object Scala04_Collection_1 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 方法
// val array = ArrayBuffer(
// ArrayBuffer(
// ArrayBuffer(1,2),ArrayBuffer(5,6)
// ), ArrayBuffer(
// ArrayBuffer(3,4),ArrayBuffer(7,8)
// )
// )
//println(array.length)
// 将整体拆分成个体的操作,称之为扁平化
// 扁平化操作只能对最外层进行操作
//println(array.flatten.flatten)
val array = Array(
"Hello Scala", "Hello Hadoop"
)
//println(array.flatten.mkString(","))
//1
println(array.flatMap(
str => {
str.split(" ")
}
).mkString(","))
//2
println(array.flatMap(
str => str.split(" ")
).mkString(",")
)
//3
println(array.flatMap(_.split(" ")).mkString(",")
)
}
}
groupBy
object Scala04_Collection_3 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 方法
// val array = ArrayBuffer(1,2,3,4)
//
// // 根据指定的规则对每一条数据进行分组
// val r = array.groupBy(
// num => {
if ( num % 2 == 0 ) {
"偶数"
} else {
"奇数"
}
// num % 2
// }
// )
//
// println(r)
val array = ArrayBuffer(
"Hello", "Scala", "Hadoop", "Spark"
)
println(array.groupBy(_.substring(0, 1)))
}
}
fold
import scala.collection.mutable.ArrayBuffer
object Scala03_Collection_3 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 方法
val array = ArrayBuffer(1,2,3,4)
val num = 5
// 折叠
//println(array.fold(5)(_ - _))
// (((5 - 1) - 2) - 3) - 4
//println(array.foldLeft(5)(_ - _))
// reversed.foldLeft(z)((x, y) => op(y, x))
// 【1,2,3,4】
// 【4,3,2,1】
// 1 - (2 - (3 - (4 - 5)))
println(array.foldRight(5)(_ - _))
//println(array.scan(5)(_ - _))
println(array.scanRight(5)(_-_))
}
}
filter
object Scala04_Collection_2 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 方法
val array = ArrayBuffer(1,2,3,4)
// filter方法可以对集合中的每一条数据进行筛选过滤
// 满足条件(true)的数据保留,不满足条件(false)的数据丢弃
val r = array.filter(
num => {
num % 2 != 0
}
)
println(r)
}
}
map
object Scala04_Collection {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 方法
val array = ArrayBuffer(1,2,3,4)
// TODO 功能函数:由集合对象提供函数执行自定义的功能
// 1. map => 映射(转换) => K->V
// a => b
// map方法需要传递一个参数,这个参数的类型为函数类型: Int => B
def mapFunction( num:Int ): Int = {
num * 2
}
//println(array.map(mapFunction))
// println(array.map(
// (num:Int) => {
// num * 2
// }
// ))
println(array.map(_*2))
}
}
reduce
匿名函数至简原则
object Scala03_Collection_2 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 方法
val array = ArrayBuffer(1,2,3,4, 5)
println(array.sum)
println(array.max)
println(array.min)
println(array.product)
// 自定义数据操作的方法
// 集合的数据无论是多少,最基本的数据操作其实都是两两计算。
// map => reduce => 简化,规约(聚合)
def reduceFunction(x : Int, y : Int): Int = {
x + y
}
println(array.reduce(reduceFunction))
println(array.reduce((x:Int, y:Int)=>{x + y}))
println(array.reduce((x:Int, y:Int)=>x + y))
println(array.reduce((x, y)=>x + y))
println(array.reduce(_ - _)) // -13
println(array.reduceLeft(_ - _)) // -13
// 【1,2,3,4】
// (((1 + 2) + 3) + 4)
// reversed.reduceLeft[B]((x, y) => op(y, x))
// 【1,2,3,4, 5】
// 【5,4,3,2,1】
// 1 - (2 - (3 - (4 - 5)))
// 【1,2,3,4】
// (1 - (2 - (3 - 4)))
println(array.reduceRight(_ - _)) // 3
}
}
sortBy
object Scala04_Collection_4 {
def main(args: Array[String]): Unit = {
// TODO - 集合 - 方法
//val array = ArrayBuffer(1,4,2,3)
val array = ArrayBuffer("1", "11"