文章目录
- 数组 Array
- 创建数组
- 直接定义
- fill
- ofDim
- tabulate
- range
- 打印数组
- toSeq
- deep
- foreach(println)
- length获取长度
- indexOf 获取元素索引
- 获取元素/修改元素
- 遍历数组
- 数组内元素转换
- filter 过滤
- found 查找元素
- 数组折叠 foldLeft
- 切片
- 拼接
- 排序
- 拷贝
- copy
- clone
数组 Array
- Array是一个固定大小的集合,原数组上无法进行添加/删除操作,可以通过++,filter 生成新数组完成目的
- 定义数组,通常数组内元素的数据类型是统一的,当你向数组中存储不同类型数据需要使用any对象
- var 定义Array 修改的数组是因为变量重新指向了新数组的内存地址,并不是数组的修改
- Array内的元素修改,并不是修改了Array地址,Array相当于容器,内部元素变了并不是容器变了。
- 数组的索引为0~~(数组长度)-1,索引没有反向索引,只有正向的。
创建数组
直接定义
val ary:Array[Int] = Array(0,1,2,3)
fill
fill(int1,int2)(填充值)
int1:维度,int2:元素数量
注意创建二维数组的时候如果声明变量需要按照二维数组声明
// 创建一维数组
val ary1: Array[Int] = Array.fill(5)(0)
// 创建二维数组
val ary7 = Array.fill(2, 3)(0)
println(ary7.deep) //Array(Array(0, 0, 0), Array(0, 0, 0))
ofDim
Array.ofDim[Int](int1,int1)
作用通fill 但是填充值默认为0,(如果变量声明了类型ofDim可以不声明)
注意创建二维数组的时候如果声明变量需要按照二维数组声明
// 创建一维数组
val ary1 = Array.ofDim[Int](3)
println(ary1) //Array( 0, 0, 0)
// 创建二维数组 通fill
val arr1 = Array.ofDim[Int](5,3)
println(arr1.deep)
//Array(Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0))
// 变量声明元素类型ofDim可以省去
val arr1:Array[Array[Int]] = Array.ofDim(5,3)
tabulate
创建数组,内容根据函数计算,可以创建1,2,3维度数组
Array.tabulate(int1,int2)(lambda)
// tabulate,创建数组,元素根据函数计算
val arr4 = Array.tabulate(5)(n => n*n)
println(arr4.deep) //Array(0, 1, 4, 9, 16)
/*
0*0,1*1,2*2....
*/
// 创建二维数组 三行四列元素 相当于 i循环三次 创建三个arry
val arr5 = Array.tabulate(3,4)((i,j)=>i+j)
println(arr5.deep)
/*
i:0 j +0,1,2,3
i:1 j + 0 1 2 3
i:2 j + 0 1 2 3
i:3 ......
*/
range
range(s,e,n)
,s起始,e结束,n步长,只能取到e-1
val arr2 = Array.range(0, 10)
println(arr2.deep) //Array(0,1,2...9)
val arr3 = Array.range(0, 10, 2)
println(arr3.deep)//Array(0,2,4,6,8)
打印数组
在scala中打印直接println数组得到的是内存地址,想要查看数组内容需要使用以下方法。
toSeq
转换为Seq类型,打印简单结构(只能打印第一层),如果是二维数组/嵌套结构使用toSeq会展示Array(内存地址1,内存地址2)
val ary:Array[Int] = Array(0,1,2,3)
println(ary.toSeq)
//WrappedArray(0,1,2,3)
val ary:Array[Array[Int]] = Array(Array(1,2,3),Array(1,2,3))
println(ary.toSeq)
//WrappedArray([I@724af044, [I@4678c730)
deep
递归打印,可以展示复杂结构,通用
val ary:Array[Array[Int]] = Array(Array(1,2,3),Array(1,2,3))
println(ary.deep)
//Array(Array(1, 2, 3), Array(1, 2, 3))
foreach(println)
foreach 一个遍历方法,结合println进行打印,效果同toSeq,也就只打印第一层,对于多维数组,或者嵌套结构会展示内存地址。
length获取长度
val ary:Array[Int] = Array(0,1,2,3)
println(ary.length) //4
indexOf 获取元素索引
indxeOf(目标元素,index位置)
同python中的index
默认返回第一个出现元素的位置,当使用第二个参数会从指定索引后查询元素第一次出现的位置
val ary1 = Array(999, 1, 2,66, 3, 4,66)
println(ary1.indexOf(66)) //3
//从索引4开始查找,找到的一个66就是数组中的最后一个
println(ary1.indexOf(66,4)) //6
获取元素/修改元素
获取元素:ary.apply(index) 等价于 ary(index)
注意与python不同,不能直接在表达式上获取元素如:Array(0,1,2,3)(0)
val ary:Array[Int] = Array(0,1,2,3)
//效果一致
print(ary.apply(0));print(ary(0))
修改元素:ary(index) = new val
val ary:Array[Int] = Array(0,1,2,3)
ary[0] = 9999
println(ary) //(9999,1,2,3)
遍历数组
通常结合for循环使用
val ary:Array[Int] = Array(0,1,2,3)
for (a<-ary){println(a)}
数组内元素转换
// 使用map方法配合toString进行转换
val arrStr1 = ary.map(z=>z.toString)
//使用匿名变量 _ 代替 z=>z
val arrStr1 = ary.map(_.toString)
filter 过滤
//filter配合 匿名函数 n => n%2 == 0
val filterarr = ary.filter(n => n%2 == 0 )
//使用匿名变量
val filterarr = ary.filter(_%2 == 0 )
found 查找元素
find
方法用于在集合中查找满足特定条件的第一个元素。它返回一个 Option
类型,该类型可以是 Some
(包含满足条件的元素)或 None
(如果没有元素满足条件)。
因此,当你使用 ary.find(n => n == 3)
时,如果数组 ary
中存在元素 3
,那么 find
方法将返回 Some(3)
。如果没有元素 3
,那么它将返回 None
。
需要注意的是,find
方法返回的是元素本身,而不是元素的索引。如果你需要查找元素的索引,你可以使用 indexOf
方法。
getOrElse
当获取不到元素时候,可以指定返回值,建议返回值与预期返回类型一致避免类型冲突。
val ary: Array[Int] = Array(0, 1, 2, 3)
// 查找元素 found_ary 返回元素本身
val found_ary = ary.find(n => n == 3)
println(found_ary) //Some(3)
// 查询不到返回None
val found_ary2 = ary.find(n => n == 999)
println(found_ary2) //None
// 当找不到899返回66 getOrElse类型可以与正常返回不一致,不建议
val found_ary3= aryzz.find(n => n == 899).getOrElse(66)
// 匿名函数写法
val found_ary = ary.find(_==3)
数组折叠 foldLeft
类似python reduct
在 Scala 中,foldLeft
方法是一个高阶函数,用于通过某种操作将集合中的所有元素组合(或折叠)成单个值。foldLeft
方法接受两个参数:一个初始值(称为“零值”),以及一个二元操作函数。
ary.foldLeft(0)(_ + _)
的作用是将数组 ary
中的所有元素与初始值 0
进行加法操作,并将结果累积起来。这里的 _ + _
是一个匿名函数,它接受两个参数并返回它们的和。
具体来说,foldLeft
方法的工作方式如下:
- 它从数组的第一个元素开始,将其与初始值(这里是
0
)一起传递给二元操作函数(这里是_ + _
)。 - 然后,它将操作的结果与数组的下一个元素一起传递给二元操作函数。
- 这个过程会一直持续,直到数组中的所有元素都被处理完毕。
fold
方法是 foldLeft
和 foldRight
的通用版本。它接受一个初始值和一个二元操作函数,并返回一个累积的结果。fold
方法的行为与 foldLeft
相同,因为它默认从集合的头部开始。
// 数组求和,积
val sum = ary.foldLeft(0)(_+_)
val product = ary.foldLeft(0)(_*_)
println(sum,product)
// 不用匿名函数
val sum = ary.foldLeft(0)((a,b)=>a+b)
切片
array.slice(start,end)
,只能取到end-1
// 数组切片
val ary:Array[Int] = Array(0,1,2,3)
val new_ary = ary.slice(0,2)
println(new_ary.toSeq) //(0,1)
拼接
new_ary = Array.concat(ar1,ar2)
== ar1+ar2
// 数组拼接 ++ 相当于 Array.concat(ary,Array(7,8,9))
val newarry = ary++Array(7,8,9)
val newarry2 = Array.concat(ary,Array(7,8,9))
println(newarry.toSeq)
排序
升序 ary.sorted
,降序:ary.sorted(Ordering[Int].reverse)
//排序
val ary1 = Array(999, 1, 2,66, 3, 4)
val ary1_sord = ary1.sorted
println(ary1_sord.toSeq) //WrappedArray(1, 2, 3, 4, 66, 999)、
// 逆序排序
ary1.sorted(Ordering[Int].reverse)
reverse
翻转
//反转与顺序无关
val reversedary = ary.reverse
println(reversedary.toSeq) //WrappedArray(4, 3, 66, 2, 1, 999)
拷贝
在 Scala 中,对于基本类型的数组(如 Int、Double、Char 等),深拷贝通常不需要特别处理,因为基本类型是不可变的。但是,对于包含对象引用的数组,你需要手动实现深拷贝,确保数组中的每个对象都被正确地复制。
copy
浅copy
copy(原数组,被copy起始位置,目标数组,copy到起始位置,copy长度)
//源数组(被copy)
val ary: Array[Int] = Array(0,1,2,3)
//创建目标数组(copy到这里)
val new_copyarray2 = Array.fill(ary.length)(0)
//数据copy
val new_copyarray3 = Array.copy(ary,0,new_copyarray2,0,ary.length)
clone
浅copy
val new_copyarray3 = ary.clone()
println(new_copyarray3.toSeq)