Scala入门学习笔记三--数组使用
前言
本篇主要讲Scala的Array、BufferArray、List,更多教程请参考:Scala教程
本篇知识点概括
- 若长度固定则使用Array,若长度可能有 变化则使用ArrayBuffer
- 提供初始值时不要使用new,复杂对象数组没有提供初始值时必须提供new
- 用()来访问元素
- 用for(elem <- arr)来遍历数组
- 用for(elem <- arr if...)...yield...来将原数组转型为新数组
- Scala数组和Java数组可以互操作
数组
1、定长数组定义:
//定义一个长度为10的数值数组
scala> val numberArray = new Array[int](10)
numberArray:Array[Int] = Array(0,0,0,0,0,0,0,0,0,0)
//定义一个长度为10的String类数组
scala> val strArray = new Array[String](10)
strArray:Array[String] = Array(null, null, null, null, null, null, null, null, null, null)
//由上可以看出,复杂对象类型在数组定义时被初始化为null,数值型呗初始化为0,并且上面复杂类型定义的时候必须加new,否则会报错
//提供初始值的定义数组
scala> val strArray2 = Array("First", "Second") //这里说明已提供初始值就不需要new
strArray2:Array[String] = Array(First, Second)
scala> strArray2(0) = "Goodbye"
strArray2:Array[String] = Array(Goodbye, Second)
2、变长数组定义 对于长度需要变化的数组,Java有ArrayList,C++有vector。Scala中的等效数据结构为ArrayBuffer
//导入可变包,Scala中的可变集合都是放在mutable中,使用时要导入
scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer
scala> val arrayBuffer = ArrayBuffer[Int]()
arrayBuffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
//在尾部添加一个值
scala> arrayBuffer += 1
res17: arrayBuffer.type = ArrayBuffer(1)
//在尾部添加多个元素
scala> arrayBuffer += (2, 3, 4, 5)
res19: arrayBuffer.type = ArrayBuffer(1, 2, 3, 4, 5)
//在尾部添加一个集合
scala> arrayBuffer ++= Array(6, 7, 8, 9)
res20: arrayBuffer.type = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
//移除最后2个元素
scala> arrayBuffer.trimEnd(2)
//在开头移除1一个元素
scala> arrayBuffer.trimStart(2)
scala> arrayBuffer
res23: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 3, 4, 5, 6, 7)
//在任意位置插入或者删除元素
scala> arrayBuffer.insert(2, 6)
//ArrayBuffer(2, 3, 6, 4, 5, 6, 7)
scala> arrayBuffer.insert(1, 2, 3, 4)
//ArrayBuffer(2, 1, 2, 3, 4, 3, 6, 4, 5, 6, 7)
scala> arrayBuffer.remove(2)
//ArrayBuffer(2, 1, 3, 4, 3, 6, 4, 5, 6, 7)
scala> arrayBuffer.remover(1, 8)
//ArrayBuffer(2, 7)
3、变长数组和定长数组转换
//变长转换长定长
scala > arrayBuffer.toArray
//Array(2, 7)
//定长转换成变长
scala>res7.toBuffer
//ArrayBuffer(2, 7)
4、遍历定长和变长数组
for(i <- 0 until.arrayBuffer.length)
println(i + ": " + a(i))
0 until.arrayBuffer.length实际上是一个方法调用,返回的是一个区间Range: 0.until(arrayBuffer.length)
for(i <- 区间)会让变量i遍历该区间的所有值
如果想要在区间中步长不为1,则:0 until (arrayBuffer.length, 2)
如果想要数组从尾端开始,则遍历的写法为:(0 until (arrayBuffer.length, 2)).reverse
Scala也提供了一个和Java增强for循环类似的for
//增强for
for(i <- arrayBuffer)
println(i + ": " + a(i))
5、数组转换 在《Scala入门学习笔记二-基本数据类型、程序控制结构》提到在for循环推导式,可以利用原来的数组产生一个新的数组。
scala> val a = Array(2, 3, 5, 7, 11)
a: Array[Int] = Array(2, 3, 5, 7, 11)
//这里产生了一个新的数组,原来的数组也在
scala> val result = for(elem <- a) yield 2 * elem
result: Array[Int] = Array(4, 6, 10, 14, 22)
如果for中使用的是定长数组,则for(...)...yield之后得到的是定长数组;如果使用的是变长数组,则会得到变长数组
- Scala也提供了另外一种做法
scala> a.filter(_ % 2 == 0).map(2 * _)
甚至
scala>a.filter(_ % 2 == 0).map{2 * _}
例子: 给定一个整数的缓冲数组,我们想要移除第一个负数之外的所有负数。有几种做法
//第一种做法:
var first = true
var n = a.length
var i = 0
while(i < n){
if(a(i) > 0) i += 1
else{
if(first) {first = false; i += 1}
else {a.remove(i); n-= 1}
}
}
//第二种做法:
//首先使用一个新数组用于记录满足条件的数组的下标
val first = true
val indexes = for(i <- 0 until a.length if first || a(i) > 0) yield {
if(a(i) < 0) first = false; i
}
//然后将元素移动到该去的位置,截断尾端
for(j <- o until indexes.length) a(j) = a(indexes(j))
a.trimEnd(a.length-indexes.length)
6、常用算法 Scala针对数组提供了一个常用的函数
//定义一个整型数组
scala> val intArr=Array(1,2,3,4,5,6,7,8,9,10)
intArr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
//求和
scala> intArr.sum
res87: Int = 55
//求最大值
scala> intArr.max
res88: Int = 10
scala> ArrayBuffer("Hello","Hell","Hey","Happy").max
res90: String = Hey
//求最小值
scala> intArr.min
res89: Int = 1
//排序
//sorted方法将数组或数组缓冲排序并返回经过排序的数组或数组缓冲,原始数组被保留
scala>val b = ArrayBuffer(1, 7, 2, 9)
b:ArrayBuffer[Int] = ArrayBuffer(1, 7, 2, 9)
scala>val bSorted = b.sorted(_<_)
bSorted: ArrayBuffer[Int] = ArrayBuffer(1, 2, 7, 9)
//toString()方法
scala> intArr.toString()
res94: String = [I@141aba8
//mkString()方法
scala> intArr.mkString(",")
res96: String = 1,2,3,4,5,6,7,8,9,10
scala> intArr.mkString("<",",",">")
res97: String = <1,2,3,4,5,6,7,8,9,10>
7、ArrayBuffer Scaladoc解析 初学者在查看sacaladoc时常常会感到困惑,不用担心,随着学习的深入,api文档中的内容将逐渐清晰 下面给出两个示例: ++=方法传入的参数类型是TraversableOnce Trait的子类,它返回的是更新好的ArrayBuffer
dropWhile传入的是一个函数,该函数返回值是布尔类型,dropWhile反回的是操作后的ArrayBuffer
8、多维数组 和Java一样,多维数组是通过数组的数组来实现的。
//第一种构造方式
val metrix = Array.ofDim[Double](3, 4) //3行 4列
//访问其中的元素
metrix(row)(column) =42
//可以创建不规则的数组,每一行的长度不相同
val triangle = new Array[Array[Int]](10)
for(i <- 0 until triangle.length)
trianglr(i) = new Array[Int](i+1)
//在创建的时候赋值
scala> val metrix = Array(Array(1, 2, 3), Array(2.3, 3.4), Array("asdf", "asdfas"))
metrix: Array[Array[_ >: String with Double with Int]] = Array(Array(1, 2, 3), Array(2.3, 3.4), Arra
y(asdf, asdfas))
//打印输出数组
scala> for(i <- metrix) println(i.mkString(" "))
1 2 3
2.3 3.4
asdf asdfas
//输出二维数组的每个值
scala> for(i <- metrix; from = i; j <- from) println(j)
1
2
3
2.3
3.4
asdf
asdfas
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Git常规操作
- 手把手教你,嘴对嘴传达 ----源码编译安装部署LAMP平台(LAMP平台与编译安装详解,Apache,MySQL与PHP源码编译安装,LAMP平台搭建论坛)
- Vue点击切换样式
- ElementUI引入到vue项目开发
- 手把手教你,嘴对嘴传达------Apache(安全优化防盗链、隐藏版本信息)
- spring框架应用系列三:切面编程(带参数)
- 排障集锦:九九八十一难之第六难!(98)Address already in use: AH00072: make_sock: could not bind to address ::80
- Vue页面中引用自定义组件
- Vue如何引用Vant组件
- js表单验证工具包
- 手把手教你,嘴对嘴传达------Nginx网站服务(访问状态统计,基于域名,端口,IP的虚拟web主机访问)
- lib-flexible引入到Vue做移动端rem布局
- 微信小程序引入VantWeapp开发
- 手把手教你,嘴对嘴传达------源码编译LNMP部署及应用 , 手动搭建discuz论坛
- 微信小程序封装api接口