Scala数组
数组定义
-
数组几乎是所有语言中最基础的数据结构。数组可索引、类型一致、长度不变。
package com.scala.code object ArrayScala { def main(args: Array[String]): Unit = { // 长度为10的整型数组,初始值为0 val nums = new Array[Int](10) // 使用()访问数据元素;下标从0开始 nums(9) = 10 // 长度为10的字符串数组,初始值为null val strs = new Array[String](10) // 省略new关键字,定义数组,scala进行自动类型推断 val arrays = Array(1, 2, 3) // 快速定义数组, val numsTest = (1 to 100).toArray } }
变长数组
-
长度按需要变换的数组ArrayBuffer。Scala 中很多数组类型都有可变、不可变两个版本,常使用不可变的数组类型,使用可变数组类型时需要显示声明;
-
使用ArrayBuffer时,需要导包 import scala.collection.mutable.ArrayBuffer;
// 定义一个空的可变长Int型数组。注意:后面要有小括号 val nums2 = ArrayBuffer[Int]() // 在尾端添加元素 nums2 += 1 // 在尾端添加多个元素 nums2 += (2,3,4,5) // 使用++=在尾端添加任何集合 nums2 ++= Array(6,7,8) // +=,++= 有相应的 -= ,--=可以做数组的删减,用法同+=,++= // 使用append追加一个或者多个元素 nums2.append(1) nums2.append(2,3) // 在下标2之前插入元素 nums2.insert(2,20) nums2.insert(2,30,30) // 移除最后2元素 nums2.trimEnd(2) // 移除最开始的一个或者多个元素 nums2.trimStart(1) // 从下标2处移除一个或者多个元素 nums2.remove(2) nums2.remove(2,2)
-
数组转换: Array <==> BufferArray定长数组与变长数组转换,toArray,变长数组转换为定长数组
//toArray,变长数组转换为定长数组 val array: Array[Int]=nums.toArray //toBuffer,定长数组转换为变长数组 val arrayBuffer: mutable.Buffer[Int]=array.toBuffer
-
数组遍历:
-
使用until,基于下标访问使用增强for循环进行数组遍历
for (i <- 0 until nums.length) { println(nums(i)) }
-
使用to,基于下标访问使用增强for循环进行数组遍历
for (i <- 0 to nums.length-1) println(nums(i))
-
使用增强for循环遍历数组元素
for (elem <- nums) println(elem)
-
多维数组
-
通过Array的ofDim方法来定义一个多维的数组,多少行,多少列
//创建一个3行4列的二维数组 val dim = Array.ofDim[Double](3,4) dim(1)(1) = 11.11 for (i <- 0 to 2; j <- 0 to 3) { print(dim(i)(j) + " ") if (j == 3) println() }
Scala数组方法
-
在Scala中对数组进行转换不会修改原始数组,而是产生一个全新的数组。
package com.scala.code object CalScala { def main(args: Array[String]): Unit = { val arr = (1 to 10).toArray // 将数组中偶数元素加倍,奇数元素丢弃 println("---------------------------") // 使用for推导式。注意:原来的数组并没有改变 val result1 = for (elem <- arr) yield if (elem % 2 == 0) elem * 2 else 0 for (i <- 0 until result1.length) { println(result1(i)) } println("---------------------------") val result2 = for (elem <- arr if elem %2 == 0) yield elem * 2 for (i <- 0 until result2.length) { println(result2(i)) } println("---------------------------") // 4 // 8 // 12 // 16 // 20 val arrtem = arr.filter(_%2==0).map(_*2).toArray for (i <- 0 to arrtem.length-1) { println(arrtem(i)) } } }
-
取数组边界值
val a1 = (1 to 10).toArray println("取第一个元素:"+a1.head) // 取最后一个元素 println("取最后一个元素:"+ a1.last) // 除了第一个元素,剩下的其他元素 val a2 = a1.tail; for (i <- 0 to a2.length - 1) { println("除了第一个元素,剩下的其他元素:"+a2(i)) } // 除了最后一个元素,剩下其他元素 val a3 = a1.init; for (i <- 0 to a3.length - 1) { println("除了最后一个元素,剩下其他元素:"+a3(i)) }
-
数组常用算法:求和,元素相乘,求最大值,求最小值,升序排列
println("---------------------------") println( Array(1,2,3,4,5,6,7,8,9,10).sum )//求和 println(Array(2,3,4).product) //元素相乘 println(Array(1,2,3,4,5,6,7,8,9,10).max )//求最大值 println(Array(1,2,3,4,5,6,7,8,9,10).min )//求最小值 println("--------------------") val arr4 = Array(1,3,2,7,6,4,8,9,10).sorted; print("升序排列:") for (i <- 0 to arr4.length - 1) { print(arr4(i)+",") }
-
数组常用方法:map,reduce,distinct,indices,count,filter
println("--------------------") val arr5 = Array(1,2,3,4,5,4,3,2,1).map(_*2) // 2,4,6,8,10,8,6,4,2 arry5每个元素中*2 for (i <- 0 to arr5.length - 1) { print(arr5(i)+",") } println("--------------------") val arr6 = Array(1,2,3,4,5,4,3,2,1).reduce(_+_) // 25 println(arr6) println("+=====================") //数据去重 1,2,3,4,5 val arry7 = Array(1,2,3,4,5,4,3,2,1).distinct for(i <- 0 until arry7.length){ print(arry7(i)+",") } println("+=====================") val arry8 = Array(1,2,3,4,5,4,3,2,1).size // 9 println(arry8) println("+=====================") val arry9 =Array(1,2,3,4,5,4,3,2,1).indices //数据索引 // Range(0, 1, 2, 3, 4, 5, 6, 7, 8) println(arry9) println("+=====================") // count计数,需要注意的是count中必须写条件 val arr10 = Array(1,2,3,4,5,4,3,2,1).count(_>3) // 3 println(arr10) val arr11 = Array(1,2,3,4,5,4,3,2,1).count(_%2==0) // 4 println(arr11) println("+=====================") // filter 过滤数据,原始数组中的数据保持不变,返回一个新的数组 val arr12 = Array(1,2,3,4,5,4,3,2,1).filter(_>3) for (i<- 0 to arr12.length -1){ // 4 5 4 println(arr12(i)) } val arr13 = Array(1,2,3,4,5,4,3,2,1).filterNot(_%2==0) for (i<- 0 to arr13.length -1){ // 1 3 5 3 1 println(arr13(i)) }
-
打印数组的方法,在REPL环境中输入数组名称即可打印数组元素,在IDEA中,print(a) / print(a.toString)都不能打印数组元素,但是使用mkString / toBuffer 是即可打印
scala> Array(10,9,8,7,6,5,4,3,2,1).toString val res1: String = [I@6ffbf0ac scala> Array(10,9,8,7,6,5,4,3,2,1).mkString(" & ") val res2: String = 10 & 9 & 8 & 7 & 6 & 5 & 4 & 3 & 2 & 1 scala> Array(10,9,8,7,6,5,4,3,2,1).mkString("<", " & ", ">") val res3: String = <10 & 9 & 8 & 7 & 6 & 5 & 4 & 3 & 2 & 1> scala> Array(10,9,8,7,6,5,4,3,2,1).toBuffer val res4: scala.collection.mutable.Buffer[Int] = ArrayBuffer(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
-
take取前4个元素;takeRight取后4个元素,原始数组中的数据保持不变,返回一个新的数组,takeWhile 从左向右提取列表的元素,直到条件不成立(条件不成立时终止)
scala> Array(1,2,3,4,5,6,7,8,9,10).take(4) val res5: Array[Int] = Array(1, 2, 3, 4) scala> Array(1,2,3,4,5,6,7,8,9,10).takeRight(4) val res6: Array[Int] = Array(7, 8, 9, 10) scala> Array(1,2,3,4,5,6,1,2,3,4).takeWhile(_<5) val res8: Array[Int] = Array(1, 2, 3, 4)
-
drop 删除前4个元素;dropRight删除后4个元素;dropWhile删除元素,直到条件不成立
scala> Array(1,2,3,4,5,6,7,8,9,10).drop(4) val res0: Array[Int] = Array(5, 6, 7, 8, 9, 10) scala> Array(1,2,3,4,5,6,7,8,9,10).dropRight(4) val res1: Array[Int] = Array(1, 2, 3, 4, 5, 6) scala> Array(1,2,3,4,5,6,1,2,3,4).dropWhile(_<5) val res2: Array[Int] = Array(5, 6, 1, 2, 3, 4)
-
将数组分为前n个,与剩下的部分,数组切片。取下标第2到第4的元素(不包括第5个元素)
scala> Array(1,2,3,4,5,6,7,8,9,10).splitAt(4) val res3: (Array[Int], Array[Int]) = (Array(1, 2, 3, 4),Array(5, 6, 7, 8, 9, 10)) scala> Array(0,1,2,3,4,5,6,7,8,9,10).slice(2,5) val res4: Array[Int] = Array(2, 3, 4)
-
拉链操作;a1,a2的长度不一致时,截取相同的长度
val a1 = Array("A","B","C") val a2 = Array(1,2,3,4) val z1 = a1.zip(a2)
-
拉链操作;a1,a2的长度不一致时,a1用 * 填充,a2用 -1 填充
val z2 = a1.zipAll(a2, "*", -1) val z3 = a1.zipAll(a2, -1, "*") // 用数组索引号填充 val z4 = a1.zipWithIndex // (A,0)(B,1)(C,2) println(z4.mkString)
-
unzip 的逆操作,拆分成2个数组
// unzip 的逆操作,拆分成2个数组 val (l1,l2) = z4.unzip // (ABC,012) println(l1.mkString,l2.mkString) // unzip3拆分成3个数组 val (l3,l4,l5) = Array((1, "one", '1'),(2, "two", '2'),(3, "three", '3')).unzip3 // (123,onetwothree,123) println(l3.mkString,l4.mkString,l5.mkString)
-
用于数组的操作符(:+、+:、++)
// :+ 方法用于在尾部追加元素;+: 方法用于在头部追加元素; // 备注:冒号永远靠近集合类型,加号位置决定元素加在前还是后; // ++ 该方法用于连接两个集合(数组、列表等),arr1 ++ arr2; val a = (1 to 4).toArray val b = (5 to 8).toArray // 分别在集合头部、尾部增加元素;连接两个集合 val c = 10 +: a val d = c :+ 9 val e = a ++ b // 说明:上述的很多方法不仅仅对Array适用,一般情况下对其他集合类型同样适用。 val list = (1 to 10).toList list.sum list.max list.take(4) list.drop(4)
-
//数组排序
val nums = Array(1, 3, 2, 6, 4, 7, 8, 5) println(nums.sorted.toBuffer) //升序 println(nums.sorted.reverse.toBuffer) //降序 println(nums.sortWith(_ > _).toBuffer) //降序 println(nums.sortWith(_ < _).toBuffer) //升序
元组及操作
- Tuple,元组。Map是键值对的集合。对偶是元组的最简单形态;
- 元组是不同类型的值的集合,元组中的元素可以是不同的数据类型
//报错,元组的元素个数上限是22个
val a = Tuple23(1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3)
// 定义元组
val a = (1, 1.2, "ad", 'd')
val b = Tuple4(1, 1.2, "ad", 'd')
println(a==b)
// Tuple的访问形式比较特殊。元组的下标从1开始
a._1
a _2
a._3
a _4
// 从元组接收数据
val (a1, a2, a3, a4), a5 = a
val (b1, _, b2, _), b5 = a
// 遍历元组,第一种方式
for(x <- a.productIterator){
println(x)
}
// 遍历元组,第二种方式
a.productIterator.foreach(x => println(x))