Scala Array
Scala 语言中提供的数组是用来存储固定大小的同类型元素。
声明数组变量并不是声明 num0、num1、…、num99 一个个单独的变量,而是声明一个就像 numbers 这样的变量,然后使用 numbers[0]、numbers[1]、…、numbers[99] 来表示一个个单独的变量。数组中某个指定的元素是通过索引来访问的。
数组的第一个元素索引为0,最后一个元素的索引为元素总数减1。
声明数组
Scala 数组声明的语法格式:
var z:Array[String] = new Array[String](3)
或
var z = Array[String](3)
以上语法中,z 声明一个字符串类型的数组,数组长度为 3 ,可存储 3 个元素。我们可以为每个元素设置值,并通过索引来访问每个元素,如下所示
z(0) = "a"; z(1) = "b"; z(2) = "c"
定义数组
var z = Array("a","b","c")
对数组进行处理
当处理数组元素时候,我们通常使用基本的 for 循环
object Test {
def main(args: Array[String]) {
var myList = Array(1.9, 2.9, 3.4, 3.5)
// 输出所有数组元素
for ( x <- myList ) {
println( x )
}
}
}
结果为:
1.9
2.9
3.4
3.5
Scala List(列表)
Scala 列表类似于数组,它们所有元素的类型都相同,但是它们也有所不同:
列表是不可变的,值一旦被定义了就不能改变,其次列表 具有递归的结构(也就是链接表结构)而数组不是。
列表的元素类型 T 可以写成 List[T]
列表基本操作:
Scala列表有三个基本操作:
- head 返回列表第一个元素
- tail 返回一个列表,包含除了第一元素之外的其他元素
- isEmpty 在列表为空时返回true
对于Scala列表的任何操作都可以使用这三个基本操作来表达。
下面就说下List常用方法:
. addString(b: StringBuilder)
将数组中的元素逐个添加到b中
var a = Array(1,2,3,4)
var b = new StringBuilder()
var c = a.addString(b) // c中的内容是 1234
. addString(b: StringBuilder, start: String, sep: String, end: String)
同上,在首尾各加一个字符串,用逗号分隔
var a = Array(1,2,3,4)
var b = new StringBuilder()
var c = a.addString(b,"{",",","}") // c中的内容是 {1,2,3,4}
. aggregate()
聚合计算,aggregate是柯里化方法,参数是两个方法,为了方便理解,我们把aggregate的两个参数,分别封装成两个方法,并把计算过程打印出来。
def main(args: Array[String]) {
val a = List(1,2,3,4)
val c = a.par.aggregate(5)(seqno,combine)
println("c:"+c)
}
def seqno(m:Int,n:Int): Int ={
val s = "seq_exp=%d+%d"
println(s.format(m,n))
return m+n
}
def combine(m:Int,n:Int): Int ={
val s = "com_exp=%d+%d"
println(s.format(m,n))
return m+n
}
//结果:
seq_exp=5+3
seq_exp=5+2
seq_exp=5+4
seq_exp=5+1
com_exp=6+7
com_exp=8+9
com_exp=13+17
c:30
. apply(i: Int)
取出指定索引处的元素
var first = apply(0) // 取出第一个元素
++
合并两个数组,并返回一个新的数组,新数组包含左右两个数组的内容。
val a = Array(1,2,3)
val b = Array(4,5,6)
val c = a ++ b
c的值 (1,2,3,4,5,6)
++:
这个方法同上一个方法类似,后面多了一个冒号,但是不同的是右边操纵数的类型决定着返回结果的类型。
+:
在数组前面添加元素,返回新的数组
val a = Array(1,2)
val c = 3 +: a
c的值是 (3,1,2)
:+
在数组后面添加元素,返回新的数组
val a = Array(1,2)
val c = 3 :+ a
c的值是 (1,2,3)
/:
foldLeft的简写,对数组中所有的元素进行相同的操作
val a = Array(1,2,3,4)
val c = (5 /: a)(_+_) // 1+2+3+4+5
val d = (5 /: a)(_*_) // 1*2*3*4*5
println("c:"+c) // c:15
println("d:"+d) // d:120
:\
foldRight的简写,foldRight就是逆序集合,然后调用foldLeft,
对数组中所有的元素进行相同的操作
::
在数组前面添加元素,要加的新值必须放在双冒号前面
val a = Array(1,2,3)
val b = 4
val c = b :: a
c的值 (4,1,2,3)
: : :
合并两个数组,必须是两个List类型的集合。并返回一个新的数组,新数组包含左右两个数组的内容。
. canEqual(that: Any): Boolean
判断2个数组是否可以比较
val a = Array(1,2,3,4)
val b = Array(33,65)
a.canEqual(b)
结果:true
. charAt(index: Int): Char
获取index索引处的字符,这个方法会执行一个隐式的转换,将Array[T]转换为 ArrayCharSequence,只有当T为char类型时,这个转换才会发生
val chars = Array('a','b','c')
println(chars.charAt(0))
结果: a
. clone()
拷贝一个数组
val a = Array(1,2,3,4)
val b = a.clone()
b结果 (1,2,3,4)
. collect()
通过执行一个并行计算(偏函数),只处理自己给的条件的其中那一部分,想要哪部分就输出那部分,剩余部分没有条件判断就直接输出,最后得到一个新的数组
val chars = Array('a','b','c')
val newchars = chars.collect(func)
println(newchars.mkString(","))
//我们通过下面的偏函数,把chars数组的小写a转换为大写的A
val func:PartialFunction[Char,Char] = {
case 'a' => 'A'
case x => x //剩余部分直接输出
}
结果是 newchars:A,b,c
. collectFirst()
在序列中查找第一个符合偏函数定义的元素,并执行偏函数计算
val arr = Array(1,'a',"b")
//定义一个偏函数,要求当被执行对象为Int类型时,进行乘100的操作
val func:PartialFunction[Any,Int] = {
case x:Int => x*100
}
//计算
val value = arr.collectFirst(func)
println("value:"+value)
//另一种写法
val value = arr.collectFirst({
case x:Int => x*100})
. combinations(n: Int)
排列组合,这个排列组合会选出所有包含字符不一样的组合,字符一样就
只选择一个,参数n表示序列长度,就是几个字符为一组
val arr = Array("a","b","c")
val newarr = arr.combinations(2)
newarr.foreach((item) => println(item.mkString(",")))
结果:
a,b
b,c
a,c
如果
val newarr = arr.combinations(3)
newarr.foreach((item) => println(item.mkString(",")))
结果:
a,b,c
.contains()
判断数组中是否包含指定的值,有就返回true,没有就返回flase
val arr = Array("a","b","c")
arr.contains("a")
结果:true
.containsSlice()
判断数组中是否包含另一个数组,数组中的值去一一比较,全部有就返回true,没有就返回flase
val a = Array(1,2,3,4)
val b = Array(2,3)
println(a.containsSlice(b))
结果:true
.copyToArray()
.copyToArray(xs: Array[A], start: Int)
.copyToArray(xs: Array[A], start: Int, len: Int)
把数组拷贝到另一个数组中,拷贝后定义的新数组如果长度不够用0补齐
val a = Array('a', 'b', 'c')
val b : Array[Char] = new Array(5)
a.copyToArray(b) //b中元素 ['a','b','c',0,0]
a.copyToArray(b,1) //b中元素 [0,'a',0,0,0] 拷贝1个值到b中下标为1的地方
a.copyToArray(b,1,2) //b中元素 [0,'a','b',0,0] 拷贝2个值到b中下标为1的地方
.copyToBuffer()
将数组中的内容拷贝到Buffer中
val a = Array('a', 'b', 'c')
val b:ArrayBuffer[Char] = ArrayBuffer()
a.copyToBuffer(b)
println(b.mkString(","))
.corresponds()
判断两个数组长度是否一样以及对应位置元素每个值是否全部符合某个条件。如果两个序列具有相同的元素数量并且每个值都符合条件p(x<y)=true,否则返回结果为true
下面代码检查a和b长度是否相等,并且a中元素是否小于b中对应位置的元素
val c = Array(1, 2, 3)
val b = Array(4, 5,6)
val a = Array(4, 1,2)
val b = Array(4, 5)
println(c.corresponds(b)(_<_)) //true 每个值全部符合条件才true
println(c.corresponds(a)(_<_)) //false 有一个值符合条件false
println(c.corresponds(d)(_<_)) //false 数组长度不一样不符合条件false
.count(p: (T) ⇒ Boolean): Int
统计符合条件的元素个数,后面跟判断条件
val a = Array(1, 2, 3)
println(a.count({
x:Int => x > 2})) // count = 1
compose
组合其他函数形成一个新的函数
def f(s: String) = "f(" + s + ")&#