Scala Array常用方法
++
- def ++[B](that: GenTraversableOnce[B]): Array[B]
- 合并集合,并返回一个新的数组,新数组包含左右两个集合对象的内容。
val a = Array(1,2)
val b = Array(3,4)
val c = a ++ b //c中的内容是(1,2,3,4)
++:
- def ++:[B >: A, That](that: collection.Traversable[B])(implicit bf: CanBuildFrom[Array[T], B, That]): That
- 这个方法同上一个方法类似,两个加号后面多了一个冒号,但是不同的是右边操纵数的类型决定着返回结果的类型。比如下面代码中List和LinkedList结合,返回结果是LinkedList类型
val a = List(1,2)
val b = scala.collection.mutable.LinkedList(3,4)
val c = a ++: b
println(c.getClass().getName())
// c的类型是:scala.collection.mutable.LinkedList
+:
- def +:(elem: A): Array[A]
- 在数组前面添加一个元素,并返回新的对象,下面添加一个元素 0
val a = List(1,2)
val c = 0 +: a // c中的内容是 (0,1,2)
:+
- def :+(elem: A): Array[A]
- 同上面的方法想法,在数组末尾添加一个元素,并返回新对象
val a = List(1,2)
val c = a :+ 0 // c中的内容是 (1,2,0)
/:
- def /:[B](z: B)(op: (B, T) ⇒ B): B
- 对数组中所有的元素进行相同的操作 ,foldLeft的简写
val a = List(1,2,3,4)
val c = (10 /: a)((x,y)=>{ println(x,y); x+y })
//(10,1)
//(11,2)
//(13,3)
//(16,4)
//c: Int = 20
:\
- def :[B](z: B)(op: (T, B) ⇒ B): B
- foldRight的简写
val a = List(1,2,3,4)
val c = (a :\ 10)((x,y)=>{ println(x,y); x+y })
//(4,10)
//(3,14)
//(2,17)
//(1,19)
//c: Int = 20
addString
- def addString(b: StringBuilder): StringBuilder
- def addString(b: StringBuilder,sep:String): StringBuilder
- def addString(b: StringBuilder,start:String,sep:String,end:String): StringBuilder
- 将数组中的元素逐个添加到b中
val a = List(1,2,3,4)
val b = new StringBuilder()
val c = a.addString(b) //1234
val c = a.addString(b,",") //1,2,3,4
val c = a.addString(b,"{",",","}") //以{开始,,分隔,}结束 {1,2,3,4}
aggregate
- def aggregate[B](z: => B)(seqop: (B, Int) => B,combop: (B, B) => B): B
- 聚合计算,aggregate是柯里化方法,参数是两个方法,为了方便理解,我们把aggregate的两个参数,分别封装成两个方法,并把计算过程打印出来。
def main(args: Array[String]) {
val a = List(1,2,3,4)
val c = a.par.aggregate(5)(seqop,combop) //par相当于多线程或分片
println("c:"+c)
}
def seqop(x:Int,y:Int):Int={
println("seqop",x,y)
x+y
}
def combop(x:Int,y:Int):Int={
println("combop",x,y)
x+y
}
/**
(seqop,5,2)
(seqop,5,1)
(seqop,5,3)
(seqop,5,4)
(combop,6,7)
(combop,8,9)
(combop,13,17)
res41: Int = 30
*/
//上面过程可以简写成
a.par.aggregate(5)(_+_,_+_)
a.par.aggregate(5)((x,y)=> x+y,_+_)
apply
- def apply(i: Int): T
- 取出指定索引处的元素
val a = Array(1,2,3,4)
a.apply(0) //等同于a(0),结果为1
canEqual
- def canEqual(that: Any): Boolean
- 判断两个对象是否可以进行比较
- 一般情况下都可以比较,结果一般都为true
val a = Array(1,2,3)
val b = Array('a','b','c')
a.canEqual(b) //true
charAt
- def charAt(index: Int): Char
- 获取index索引处的字符,这个方法会执行一个隐式的转换,将Array[T]转换为 ArrayCharSequence,只有当T为char类型时,这个转换才会发生。
val chars = Array('a','b','c')
println("c:"+chars.charAt(0)) //结果 a
clone
- def clone(): Array[T]
- 创建一个副本
val chars = Array('a','b','c')
println(a.apply(2))
val newchars = chars.clone()
collect
- def collect[B](pf: PartialFunction[A, B]): Array[B]
- 通过执行一个并行计算(偏函数),得到一个新的数组对象
val fun:PartialFunction[Char,Char]={
case 'a' => 'A'
case 'b' => 'B'
case x => x
}
val chars = Array('a','b','c')
chars.collect(fun) //结果为A,B,c
collectFirst
- def collectFirst[B](pf: PartialFunction[T, B]): Option[B]
- 在序列中查找第一个符合偏函数定义的元素,并执行偏函数计算
val arr = Array(1,'a','b')
val fun:PartialFunction[Any,Int]={
case x:Int => x*100
}
arr.collectFirst(fun) //结果为some(100)
//等同于下面的语句
arr.collectFirst({case x:Int => x*100})
combinations
- def combinations(n: Int): collection.Iterator[Array[T]]
- 排列组合,这个排列组合会选出所有包含字符不一样的组合,对于 “abc”、“cba”,只选择一个,参数n表示序列长度,就是几个字符为一组
val arr = Array("a","b","c")
arr.combinations(2).foreach(x=>println(x.mkString))
/**
结果如下
ab ac dc
*/
contains
- def contains[A1 >: A](elem: A1): Boolean
- 序列中是否包含指定对象
val a = List(1,2,3,4)
println(a.contains('2')) //true
containsSlice
- def containsSlice[B](that: GenSeq[B]): Boolean
- 判断当前序列中是否包含另一个序列
val a = List(1,2,3,4)
val b = List(2,3)
println(a.containsSlice(b)) //true
copyToArray
- def copyToArray(xs: Array[A]): Unit
- 此方法还有两个类似的方法
- copyToArray(xs: Array[A], start: Int): Unit
- copyToArray(xs: Array[A], start: Int, len: Int): Unit //start指b的起始位置下标,len指a的长度
val a = Array('a','b','c')
val b:Array[Char] = new Array(5)
a.copyToArray(b) //'a','b','c',?,?
val c:Array[Char] = new Array(5)
a.copyToArray(c,1) //?,'a','b','c',?
val d:Array[Char] = new Array(5)
a.copyToArray(d,1,2) //?,'a','b',?,?
copyToBuffer
- def copyToBuffer[B >: A](dest: Buffer[B]): Unit
- 将数组中的内容拷贝到Buffer中
- 导入包:import scala.collection.mutable._
val a = Array('a', 'b', 'c')
val b:ArrayBuffer[Char] = ArrayBuffer()
a.copyToBuffer(b)
//b:scala.collection.mutable.ArrayBuffer[Char] = ArrayBuffer(a, b, c)
corresponds
- def corresponds[B](that: GenSeq[B])(p: (T, B) ⇒ Boolean): Boolean
- 判断两个序列长度以及对应位置元素是否符合某个条件。如果两个序列具有相同的元素数量并且p(x, y)=true,返回结果为true;但若是两个序列的长度不等,或是其中一项不符合条件,返回结果均为false
- 下面代码检查a和b长度是否相等,并且a中元素是否小于b中对应位置的元素
val a = Array(1, 2, 3)
val b = Array(4, 5,6)
println(a.corresponds(b)(_<_)) //true
count
- def count(p: (T) ⇒ Boolean): Int
- 统计符合条件的元素个数
val a = Array(1, 2, 3)
println(a.count({x:Int => x > 2})) // count = 1
diff
- def diff(that: collection.Seq[T]): Array[T]
- 计算当前数组与另一个数组的不同。返回当前数组中没有在另一个数组中出现的元素
- 比较对象时比较地址
val a = Array(1, 2, 3,4)
val b = Array(4, 5,6,7)
println(a.diff(b).mkString) //1,2,3
distinct
- def distinct: Array[T]
- 去除当前集合中重复的元素,只保留一个
val a = Array(1, 2, 3,4,4,5,6,6)
println(a.distinct.mkString(",")) // 1,2,3,4,5,6
drop
- def drop(n: Int): Array[T]
- 将当前序列中前 n 个元素去除后,作为一个新序列返回
val a = Array(1, 2, 3,4)
val c = a.drop(2)
println(c.mkString(",")) // 3,4
dropRight
- def dropRight(n: Int): Array[T]
- 功能同 drop,去掉尾部的 n 个元素
val a = Array(1, 2, 3,4)
val c = a.dropRight(2)
println(c.mkString(",")) // 1,2
dropWhile
- def dropWhile(p: (T) ⇒ Boolean): Array[T]
- 去除当前数组中符合条件的元素
- 这个需要一个条件,就是从当前数组的第一个元素起,就要满足条件,直到碰到第一个不满足条件的元素结束(即使后面还有符合条件的元素),否则返回整个数组
//下面去除大于2的,第一个元素 3 满足,它后面的元素 2 不满足,所以返回 2,3,4
val a = Array(3,2,3,4)
val b = a.dropWhile( {x:Int => x > 2} ) //2,3,4
//如果数组 a 是下面这样,第一个元素就不满足,所以返回整个数组 1,2,3,4
val a = Array(1,2,3,4) //1,2,3,4
endsWith
- def endsWith[B](that: GenSeq[B]): Boolean
- 判断是否以某个序列结尾
val a = Array(3, 2, 3,4)
val b = Array(3,4)
println(a.endsWith(b)) //true
exists
- def exists(p: (T) ⇒ Boolean): Boolean
- 判断当前数组是否包含符合条件的元素
val a = Array(3, 2, 3,4)
a.exists(x=>{println(x);x>3})
/**
结果如下
3
2
3
4
true
*/
filter
- def filter(p: (T) ⇒ Boolean): Array[T]
- 取得当前数组中符合条件的元素,组成新的数组返回
val a = Array(3, 2, 3,4)
val b = a.filter( {x:Int => x> 2} )
println(b.mkString(",")) //3,3,4
filterNot
- def filterNot(p: (T) ⇒ Boolean): Array[T]
- 与上面的 filter 作用相反
val a = Array(3, 2, 3,4)
val b = a.filter( {x:Int => x> 3} )
println(b.mkString(",")) //3,2,3
find
- def find(p: (T) ⇒ Boolean): Option[T]
- 查找第一个符合条件的元素
val a = Array(1, 2, 3,4)
val b = a.find( {x:Int => x>2} )
println(b) // Some(3)
flatMap
- def flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): Array[B]
- 对当前序列的每个元素进行操作,结果放入新序列返回,参数要求是GenTraversableOnce及其子类
val a = Array(1, 2, 3,4)
val b = a.flatMap(x=>1 to x)
println(b.mkString(","))
/**
1,1,2,1,2,3,1,2,3,4
从1开始,分别于集合a的每个元素生成一个递增序列,过程如下
1
1,2
1,2,3
1,2,3,4
*/
flatten
- def flatten[U](implicit asTrav: (T) ⇒ collection.Traversable[U], m: ClassTag[U]): Array[U]
- 将二维数组的所有元素联合在一起,形成一个一维数组返回
val dArr = Array(Array(1,2,3),Array(4,5,6))
val c = dArr.flatten
println(c.mkString(",")) //1,2,3,4,5,6
fold
- def fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1
- 对序列中的每个元素进行二元运算,和aggregate有类似的语义,但执行过程有所不同,我们来对比一下他们的执行过程。
def seqop(m:Int,n:Int): Int ={
println("seqop,"+m+","+n)
}
val a = Array(1, 2, 3,4)
val b = a.fold(5)(seqop)
/** 运算过程
seqop,5,1
seqop,6,2
seqop,8,3
seqop,11,4
最终结果为15
*/
//简写 val b = (a :\ 5)(_+_)
- 看上面的运算过程发现,fold中,seqop是把初始值顺序和每个元素相加,把得到的结果与下一个元素进行运算
- 与aggregate不同的是,seqop是把初始值与每个元素相加,其结果不参与下一步运算,而aggregate中,会把seqop的结果放入到另一个序列中,有第二个方法combine进行处理
foldLeft
- def foldLeft[B](z: B)(op: (B, T) ⇒ B): B
- 从左到右计算,简写方式:def /:[B](z: B)(op: (B, T) ⇒ B): B
- 和fold相同
foldRight
- def foldRight[B](z: B)(op: (B, T) ⇒ B): B
- 从右到左计算,简写方式:def :[B](z:
B)(op: (T, B) ⇒ B): B
forall
- def forall(p: (T) ⇒ Boolean): Boolean
- 检测序列中的元素是否都满足条件 p,如果序列为空,返回true
val a = Array(1, 2, 3,4)
val b = a.forall( {x:Int => x>0}) //true
val b = a.forall( {x:Int => x>2}) //false
foreach
- def foreach(f: (A) ⇒ Unit): Unit
- 遍历序列中的元素,进行 f 操作
val a = Array(1,2,3,4)
a.foreach(println)
/**
1
2
3
4
*/
a.foreach(x=>println(x>2))
/**
false
false
true
true
*/
groupBy
- def groupBy[K](f: (T) ⇒ K): Map[K, Array[T]]
- 按条件分组,条件由 f 匹配,返回值是Map类型,每个key对应一个序列
- groupBy可以跟模式匹配
val a = Array(1,2,3,4)
val b = a.groupBy(x=>x match {
case x if(x<3) => "small"
case x if(x==3) => "ok"
case x => "big"
})
//b:scala.collection.immutable.Map[String,Array[Int]] = Map(ok -> Array(3), small -> Array(1, 2), big -> Array(4))
grouped
- def grouped(size: Int): collection.Iterator[Array[T]]
- 按指定数量分组,每组有 size 数量个元素,返回一个集合
val a = Array(1, 2, 3,4,5)
val b = a.grouped(3).toList
b.foreach(x => println(x.mkString(",")))
/**
1,2,3
4,5
*/
hasDefiniteSize
- hasDefiniteSize: Boolean
- 检测序列是否存在有限的长度,对应Stream这样的流数据,返回false
val a = Array(1, 2, 3,4,5)
println(a.hasDefiniteSize) //true
println(a.toStream.hasDefiniteSize) //false
head
- def head: T
- 返回序列的第一个元素,如果序列为空,将引发错误
val a = Array(1, 2, 3,4,5)
println(a.head) //1
headOption
- def headOption: Option[T]
- 返回序列Option类型对象的第一个元素,就是scala.Some 或者 None,如果序列是空,返回None
val a = Array(1, 2, 3,4,5)
println(a.headOption) //Some(1)
tail
- def tail: Array[T]
- 返回序列除第一位元素的所有元素,即第二个元素到最后一个元素的数组
val a = Array(1, 2, 3,4,5)
println(a.tail) //2, 3, 4, 5
tails
- def tails: Iterator[Array[Int]]
- 返回从第一位元素到最后一位元素,第二位元素到最后一位元素…一直到为空的一个数组的迭代器
val a = Array(1, 2, 3,4,5)
val b = a.tails.toList
/**
结果如下
b: List[Array[Int]] = List(Array(1, 2, 3, 4, 5), Array(2, 3, 4, 5), Array(3, 4, 5), Array(4, 5), Array(5), Array())
*/
今天就先整理了这么多的方法,下一篇博客Scala Array常用方法(二),我们再接着更新Scala中Array的的常用方法。