【大纲】
【正文】
1.数组
1.1.概念
数组是用来存储多个相同类型元素的容器,每个元素都有编号 = 下标 = 脚标 = 索引,索引都是从1开始的
scala中有2种数组,定长数组和变长数组
1.2.分类
1.2.1.Array
1.2.1.1.特点
定长数组Array的长度不允许变、元素值可变、元素可重复、存取有序
1.2.1.2.定义语法
0.指定长度定义空数组
val/var a = new Array[元素类型](数组长度) # 效果:每个元素被初始化为默认值
1.指定元素定义数组
val/var a = Array(8, 9, 1) # 注意:元素类型可省略,会自动推断。# 注意:第一个元素就是head元素,后边的所有元素就是tail列表。最后一个元素就是last元素,前边所有的元素就是init元素
示例
# Array 定义
object Array1 {
def main(args: Array[String]): Unit = {
val a = new Array[Int](10)
println(a) // 效果:[I@23223dd8
println(a.getClass) // 效果:class [I
val b = Array("java", "scala", "python")
println(b) // 效果:[Ljava.lang.String;@4ec6a292
println(b.getClass) // 效果:class [Ljava.lang.String;
}
}
1.2.2.ArrayBuffer
1.2.2.1.特点
变长数组ArrayBuffer的长度和元素值都可变,元素可重复、存取有序
1.2.2.2.定义语法
0.定义空数组
import scala.collection.mutable.ArrayBuffer
val/var ab = ArrayBuffer[数据类型]() # 注意: 此时默认数组长度为0,无元素值,还不能用索引操作
1.指定元素定义数组
import scala.collection.mutable.ArrayBuffer
val/var ab = ArrayBuffer(7, 3, 5) # 注意:元素类型可省略,会自动推断。# 注意:第一个元素就是head元素,后边的所有元素就是tail列表。最后一个元素就是last元素,前边所有的元素就是init元素
示例
# ArrayBuffer 定义
object ArrayBuffer1 {
def main(args: Array[String]): Unit = {
// 定义空数组
val ab = new ArrayBuffer[Int]()
println(ab) // 效果:ArrayBuffer()
// 指定元素定义数组
val ab2 = ArrayBuffer("java", "scala", "pathon")
println(ab2) // 效果:ArrayBuffer(java, scala, pathon)
}
}
1.2.2.3.可变数组集合通用API
# 注意:数组、列表、集、映射通用
0.+=向末尾添加多个元素
对象 += 新元素
对象 += (新元素1, 新元素2)
对象.append(新元素) /
Set对象.add(新元素) /
Map对象.put(key, value) /
Map对象(key) = value
对象.append(新元素1, 新元素2) # 注意:Set无、Map无
1.‐=删除多个元素
对象 ‐= 旧元素 /
Map对象 -= 旧key
对象 ‐= (旧元素1, 旧元素2) /
Map对象 -= (旧key1, 旧key2)
2.++=拼接
对象A ++= 对象B # 注意:对象B可以是数组、列表、集 # 注意:但A是Map时B只能是Map
3.‐‐=裁剪
对象A ‐‐= 对象B # 注意:对象B可以是数组、列表、集
4.向指定索引添加多个元素
对象.insert(索引, 新元素1, 新元素2)
# 注意:Set无索引、Map无索引
5.按索引删除元素
val 被删掉的元素 = 对象.remove(索引) /
val 被删掉的元素 = Set对象.remove(旧元素) /
val 被删掉的key的value = Map对象.remove(旧key) # 注意:返回值Some类型
6.从指定索引开始删除多个元素
对象.remove(startIndex, count) # 注意:返回值Unit
# 注意:Set无、Map无
7.清空所有元素
对象.clear
示例
# ArrayBuffer 增删改
object ArrayBuffer1 {
def main(args: Array[String]): Unit = {
val ab = ArrayBuffer("hadoop", "spark", "flink")
ab += "flume"
println(ab) // 效果:ArrayBuffer(hadoop, spark, flink, flume)
ab -= "hadoop"
println(ab) // 效果:ArrayBuffer(spark, flink, flume)
ab ++= Array("hive", "sqoop")
println(ab) // 效果:ArrayBuffer(spark, flink, flume, hive, sqoop)
ab --= Array("sqoop", "spark")
println(ab) // 效果:ArrayBuffer(flink, flume, hive)
val a = ArrayBuffer(4, 1, 6, 5, 2, 3)
a.insert(2, 0, 0, 0)
println(a) // 效果: ArrayBuffer(4, 1, 0, 0, 0, 6, 5, 2, 3)
val removeValue = a.remove(2)
println(removeValue) // 效果:0
println(a) // 效果:ArrayBuffer(4, 1, 0, 0, 6, 5, 2, 3)
a.remove(2, 4)
println(a) // 效果:ArrayBuffer(4, 1, 2, 3)
}
}
1.3.数组集合通用API
# 注意:数组、列表、集、映射通用
0.按索引访问元素
val a = 对象(索引) /
val a = Map对象.get(key) # 效果:key不存在,返回None /
val a = Map对象.getOrElse(key, value默认值) # 效果:如果key不存在,默认值将作为value返回 /
val a = Map对象(key) # 效果:key不存在会报错
或
val a = 对象.apply(索引) /
val value = Map对象.apply(key)
# 注意:Set无
1.按索引修改元素,返回新对象
对象(索引) = 新元素
# 注意:immutable.List无
# 注意:Set无、Map无
或
val 新对象 = 对象.updated(索引, 新元素) /
val 新对象 = Map对象.updated(key, 新value)
# 注意:Set无
2.子序列替换,返回新对象
val b = 对象.patch(被替换的起始索引i, 新子序列对象a, 替换掉n个元素) #效果:从索引i开始,用子序列a替换n个元素
# 注意:Set无、Map无
3.判断是否为空
val boolean = 对象.isEmpty
4.判断是否包含
val boolean = 对象.contains(指定元素) / val boolean = Map对象.contains(key)
或
val boolean = Set对象.apply(指定元素)
5.判断是否相同
判断元素是否相等
对象A == 对象B
判断地址值是否相等
对象A eq 对象B
判断元素内容全部相同且迭代顺序相同
val Boolean = 对象A.sameElements(对象B)
6.获取长度
val l = 对象.size
val l = 对象.length # 注意:Set无、Map无
7.遍历
方式一 iterator 推荐
val a = List(1,2,3)
val it = a.iterator
while(it.hasNext){
val b = it.next()
println(b)
}
方式二 foreach 推荐
对象.foreach{x => 对元素x的处理}
方式三 for
for(元素 <‐ 对象)println(元素)
方式四 for + to
for(索引 <‐ 0 to 对象.length ‐ 1)println(对象(索引))
方式五 for + until
for(索引 <‐ 0 until 对象.length)println(对象(索引))
8.分组遍历
val a = List(1,2,3,4,5)
val it = a.grouped(2) // 2个元素放一组进行分组,返回个Iterator
while(it.hasNext){
println(it.next()) // 效果:List(1, 2) List(3, 4) List(5)
}
9.获取head元素
val a = 对象.head
val a = 对象.headOption // 注意:返回值是Option类型
10.获取tail列表
val a = 对象.tail
11.获取last元素
val a = 对象.last
val a = 对象.lastOption // 注意:返回值是Option类型
12.获取init列表
val a = 对象.init
13.获取第2个元素
val secondValue = 对象.tail.head
14.获取前n个元素,返回新对象
val l = 对象.take(元素个数)
15.丢弃前n个元素,剩余元素以新对象返回
val l = 对象.drop(n)
16.按索引截取部分,返回新对象
val a = 对象.slice(起始索引, 截止索引) # 注意:[起始索引, 截至索引)
17.获取第一个满足条件的元素,返回Option
val a = 对象.find(x => x % 2 == 0)
18.获取指定元素第一次出现的索引
val index = 对象.indexOf(指定元素)
# 注意:Set无、Map无
19.获取指定元素最后一次出现的索引
cal index = 对象.lastIndexOf(指定元素)
20.根据条件获取指定元素第一次出现的索引
val b = a.indexWhere(x => x < 5 && x % 2 ==0)
val b = a.indexWhere(x => x < 5 && x % 2 ==0, 起始索引) # 效果:从起始索引开始向后找
# 注意:Set无、Map无
21.根据条件获取指定元素最后一次出现的索引
val b = 对象.lastIndexWhere(x => x < 7 && x % 2 ==0)
val c = 对象.lastIndexWhere(x => x % 2 == 0, 终止索引) # 效果:从0索引开始找到终止索引为止
# 注意:Set无、Map无
22.获取子序列第一次出现的索引
val d = 对象.indexOfSlice(子序列对象)
val d = a.indexOfSlice(Seq(4,6), 起始索引) # 效果:从起始索引开始向后找
# 注意:Set无、Map无
23.是否以指定子序列开头
val a = 对象.startsWith(子序列对象)
# 注意:Set无、Map无
24.是否以指定子序列结尾
val b = 对象.endsWith(子序列对象)
# 注意:Set无、Map无
25.是否包含指定元素
val boolean = 对象.contains(指定元素) /
val value = 对象.contains(key)
26.是否包含指定子序列
val b = 对象.containsSlice(子序列对象)
# 注意:Set无、Map无
27.向头部添加元素,返回新对象 (不用)
val a = 1 +: 数据类型(2,3,4) # 推荐
val a = 数据类型(2,3,4).+:(1) # 注意:+:符号Set无、Map无
val a = 1 :: List(2,3,4) # 注意:::符号只有List有
val a = List(2,3,4).::(1) # 注意:::符号只有List有
val a = 1 :: 2 :: 3 :: Nil # 注意:::符号只有List有 # 效果:向List头部连续添加元素
28.向尾部添加元素,返回新对象 (不用)
val a = 数据类型(3,6,7) :+ 2
# 注意:Set无、Map无
29.获取各元素的和(元素必须是数字类型)
val a = 对象.sum
# 注意:Map?
30.获取各元素的乘积(元素必须是数字类型)
val a = 对象.product
31.获取元素最大值
val a = 对象.max # 效果:Map先看key,key相同再比较value
32.获取元素最小值
val a = 对象.min # 效果:Map先看key,key相同再比较value
33.计算满足指定条件的元素的个数
val a = 对象.count(x => x % 2 == 0)
34.判断元素是否满足指定条件
val Boolean = 对象.forall(x => x % 2 ==0) // 效果:所有元素都是偶数才返回true
val Boolean = 对象.exists(x => x % 2 ==0) // 效果:有一个元素是偶数就返回true
35.反转,返回新对象
val a = 对象.reverse # 注意:Set无、Map无
36.升序排序,返回新对象
val a = 对象.sorted # 注意:Set无、Map无
37.元素按要求排序,返回新对象
val a = 对象.sortBy(x => ‐x) # 注意:Set无、Map无
38.去重,返回新对象
val a = 对象.distinct # 注意:Set无、Map无
39.按指定索引切分为二,返回新对象
val a = 数据类型(元素1, 元素2, 元素3, 元素4, 元素5)
val b = a.splitAt(索引) # 效果:(数据类型(元素1, 元素2),数据类型(元素3, 元素4, 元素5))
40.使用迭代器,返回新对象
val 新对象 = for(元素 <‐ 对象) yield 对元素操作 # 效果:新对象的数据类型和旧的一样
41.过滤,返回新对象
方式一 filter
val 新对象 = 对象.filter(x => x % 2 == 0) # 效果:满足过滤条件的元素存入新对象 # 注意:x 代表当前元素,也可用_代表当前元素
或
val 新对象 = Map对象.filterKeys(x => x % 2 ==0) # 效果:过滤满足条件的key存入新对象
方式二 collect(偏函数)
val a = Map("k1"->1,"k2"->2,"k3"->3)
val b = a.collect({
case x if x._2 % 2 == 0 => x
}) # 效果:Map(k2 -> 2)
42.map操作,返回新对象
val 新对象 = 对象.map(x => x + 1) # 效果:取出对象中每个元素,进行处理后,存入新对象 # 注 意:x代表当前元素,也可用_代表当前元素
43.按元素分组
val a = 数据类型(元素1, 元素2, 元素3)
val b = a.groupBy(x => x %2 == 0)
44.类型转换
转String
方式一 mkString 推荐
val s = 对象.mkString # 效果:取出各元素,直接拼接成String
val s = 对象.mkString(",") # 效果:取出各元素,用,拼接成String
val s = 对象.mkString("<", "‐", ">") # 效果:取出各元素,用,拼接成String,首拼上 <,尾拼上>
方式二 调用的java的toString() 不用
val s = 对象.toString() # 效果:数组的话是地址值,其他可显示出元素值
不可变转可变
val a = 不可变对象.toBuffer / val a = 不可变Set对象.toSet / val a = 不可变Map对象.toMap
转XX
val a = 对象.toXX
45.+添加指定元素,返回新对象
val a = Map/Set对象 + (新元素1, 新元素2)
46.‐删除指定元素,返回新对象
val a = Set对象 ‐ (旧元素1, 旧元素2) /
val a = Map对象 ‐ (旧key1, 旧key2)
47.俩对象拼接,返回新对象
val a = Traversable.concat(对象A, 对象B, 对象C) # 推荐 # 效果:新对象数据类型是List, 多个对象拼接时不会产生中间结果,但是用多个++拼接多个对象时每次++都会产生一个新的临时结果占用内存多
val a = 对象A ++ 对象B # 效果:新对象的数据类型和A一样
val a = 数据类型("A") ++: 数据类型("B")
val a = List("A") ::: List("B") # 注意::::符号只有List有
48.多维
创建二维
val a = 数据类型(元素1, 元素2) # 一维
val b = 数据类型(元素3, 元素4) # 一维
val c = 数据类型(a, b) # 二维
遍历二维
for(i <‐ c)println(i.mkString("‐"))
49.集合填充 # 注意:仅适用于Traversable
方式一 fill快速生产指定数量的元素
val a = Traversable.fill(3)("wsy") // 注意:第1个参数列表中只有1个参数代表创建个一维集合,第1个参数列表中的第1个参数3代表一维List有3个元素,第2个参数列表代表集合中每个元素都是"wsy"
val b = Traversable.fill(3)(Random.nextInt(100)) // 注意:第1个参数列表中只有1个参数代表创建个一维集合,第1个参数列表中的第1个参数3代表一维List有3个元素,第2个参数列表代表集合中每个元素都是随机出来的一个值
val c = Traversable.fill(3,4)("wsy") // 注意:第1个参数列表中有2个参数代表创建个二维集合,第1个参数列表中的第1个参数3代表外维List有3个元素,第1个参数列表中的第2个参数4代表内维List有4个元素,第2个参数列表代表集合中每个元素都是"wsy"
val d = Traversable.fill(3,4,1)("wsy") // 注意:第1个参数列表中有3个参数代表创建个三维集合,第1个参数列表中的第1个参数3代表外维List有3个元素,第1个参数列表中的第2个参数4代表中维List有4个元素,第1个参数列表中的第3个参数1代表内维List有1个元素,第2个参数列表代表集合中每个元素都是"wsy"
方式二 iterate根据指定条件生产指定个数的元素
val a = Traversable.iterate(1,5)(x => x * 2) // 效果:1是初始值,共5个元素,初始值*2作为第1个元素,第1个元素*2作为第2个元素,依次类推
方式三 range生成某个区间内的指定间隔的所有数据
val a = Traversable.range(1, 20, 5) // 效果:从数字1开始,到数字19,间隔5的所有数据
val a = Traversable.range(1, 20) // 注意:不指定间隔时默认间隔是1
50.拉链操作,返回新对象
val a = 数据类型(元素1, 元素2)
val b = 数据类型(元素3, 元素4)
val c = a zip b # 效果:数据类型((元素1, 元素3), (元素2, 元素4)) # 注意:a和b如果长度不一样,未对齐的元素会直接丢弃;如果有的值是null,会被当作正常元素
51.解链操作,返回新对象
val c = 数据类型((元素1, 元素3), (元素2, 元素4))
val ab = c.unzip # 效果:(数据类型(元素1, 元素2), 数据类型(元素3, 元素4))
52.扁平化操作,返回新对象
val a = 数据类型(数据类型(元素1, 元素2), 数据类型(元素3, 元素4), 数据类型(元素5, 元素6))
val b = a.flatten // 效 果:数据类型(元素1, 元素2, 元素3, 元素4, 元素5, 元素6)
# 注意:Map?
53.按照索引生成元组
val a = Iterable("A", "B", "C", "D", "E") # 注意:Iterable换成数组、集合都通用
val b = a.zipWithIndex // 效果:List((A,0), (B,1), (C,2), (D,3), (E,4))
54.取并集,返回新对象
对象A.union(对象B) # 注意:Map无
55.取交集,返回新对象
val a = 对象A.intersect(对象B) # 注意:Map无
56.取差集,返回新对象
val a = 对象A.diff(对象B) # 效果:对象A有但B没有的元素 # 注意:Map无
57.m*n矩阵转置
val a5 = Traversable(Traversable(1,2,3), Traversable(4,5,6)) // 注意:Traversable可换成任何集合、数组
val a6 = a5.transpose // 效果:List(List(1, 4), List(2, 5), List(3, 6)) // 注意:返回值类型和原来的一样
58.scan操作,返回新对象
val c = Traversable(1,2,3,4,5) // 注意:Traversable可换成任意集合、数组
val d = c.scan(0)((x,y) => x + y) // 注意:第1个参数列表是初始值,第2个参数列表是函数
println(d) // 效果:List(初始值0, 初始值与第1个元素的计算结果1, 计算结果与第2个元素的计算结果3, 计算结果与第3个元素的计算结果6, 计算结果与第4个元素的计算结果10, 计算结果与第5个元素的计算结果15) // 注意:数据类型和原来一样
示例
# 数组常用算法
object ArrayBuffer1 {
def main(args: Array[String]): Unit = {
val a = ArrayBuffer(4, 1, 6, 5, 2, 3)
println(a.sum) // 效果:21
println(a.max) // 效果:6
println(a.min) // 效果:1
val b = a.sorted
for(i <- b)print(i) // 效果:123456
println()
val c = b.reverse
for(i <- c)print(i) // 效果:654321
println()
for(i <- a)print(i) // 效果:416523
}
}
# 数组生成迭代器 -- yield
object HelloScala {
def main(args: Array[String]): Unit ={
val arr = Array(1, 2, 3, 4, 5)
val dealArr = for(e <- arr) yield e * 2 // 数组转换 -- yield
for(e <- dealArr)println(e)
}
}
# 效果:2 4 6 8 10
# 数组过滤 -- filter
object HelloScala {
def main(args: Array[String]): Unit ={
val ab = ArrayBuffer(1, 2, 3, 4)
val dealAb = ab.filter(_ % 2 == 0) // 数组转换 -- filter
for(e <- dealAb) println(e)
}
}
# 效果:2 4
# 数组映射 -- map
object HelloScala {
def main(args: Array[String]): Unit ={
val ab = ArrayBuffer(1, 2, 3)
val dealAb = ab.map(_ + 1) // 数组转换 -- map
for(e <- dealAb) println(e)
}
}
# 效果: 2 3 4
# 数组转String
object HelloScala {
def main(args: Array[String]): Unit ={
val arr = Array(3, 1, 2)
val dealArr = arr.mkString // array转String
println(dealArr)
}
}
# 效果:312
# 数组转String
object HelloScala {
def main(args: Array[String]): Unit ={
val arr = Array(3, 1, 2)
val dealArr = arr.mkString("-") // array转String
println(dealArr)
}
}
# 效果:3-1-2
# 数组转String
object HelloScala {
def main(args: Array[String]): Unit ={
val arr = Array(3, 1, 2)
val dealArr = arr.mkString("[","-","]") // array转String
println(dealArr)
}
}
# 效果:[3-1-2]
# 多维数组
object HelloScala {
def main(args: Array[String]): Unit ={
val arr1 = Array(1, 2)
val arr2 = Array(3, 4)
// 创建二维数组
val Arr2V = Array(arr1, arr2)
// 遍历二维数组
for(arr <- Arr2V)println(arr.mkString("-"))
}
}
# 效果:1-2 3-4
2.元组Tuple
2.1.概念
元组Tuple一般用来存储多个不同数据类型的值
元组的长度和内容都不可变
元组的元素可重复、存取有序
2.2.定义语法
0.通用定义语法
val/var t = (元素1, 元素2)
1.二元组定义语法
val/var t = 元素1 -> 元素2
# 注意:
0.只适用于二元组,即元组只有2个元素时
1.二元组会自动和key-value结构进行转换
2.3.API
# 注意:元组的API很特别,几乎只适合自己,和其他类型的API不通用
0.按索引获取元素
val a = 元组对象._1 # 注意:_1代表获取第1个元素,_2代表获取第2个元素
1.遍历
val t3 = ("q", 1, 1.2, 'w')
val it = t3.productIterator // 获取元组的迭代器对象
for(i <- it)println(i)
2.Array(Tuple)转Map
val a = Array(("tom", 8), ("Jerry", 9))
val m = a.toMap
示例
object Tuple1 {
def main(args: Array[String]): Unit = {
val t3 = ("q", 1, 1.2, 'w')
val it = t3.productIterator
for(i <- it)print(i) // 效果:q11.2w
println()
println(t3._1) // 效果:q
}
}