提取元素
All:
val v: T = arr.head //提取第一个元素
val v: Option[T] = arr.headOption //提取第一个元素
val v: Int = arr.last //提取最后一个元素
val v: Option[T] = arr.lastOption //提取最后一个元素
val v: T = arr(index:Int) //提取指定下标位置元素
val v: T = arr.apply(0) //提取指定下标位置元素
val v: T = arr.applyOrElse(index:Int,{_:Int=>value:T}) //接收2个参数,参数1是调用的参数,参数2是回调函数,如果参数1调用的参数匹配,返回匹配的值,否则调用回调函数。
val v: Array[T] = arr.take(size:Int) //从左边取size个元素
val v: Array[T] = arr.takeRight(size:Int) //从右边取size个元素
val v: Array[T] = arr.takeWhile(p:T=>Boolean) //从下标0开始取,碰到不满足条件p的就结束
val v: Array[T] = arr.filter(p:T=>Boolean) //提取满足条件p的所有元素
val v: Array[T] = arr.filterNot(p:T=>Boolean) //提取不满足条件p的所有元素
val v: Array[T] = arr.collect(pf:PartialFunction[T,B]{T=>B}) //提取所有满足偏函数pf的元素
val v: Option[T] = arr.collectFirst(pf:PartialFunction[T,B]{T=>B}) //提取满足偏函数pf的第一个Option元素
val v: Option[T] = arr.find(p:T=>Boolean) //提取第一个满足偏函数的元素
val v: Array[T] = arr.slice(from:Int,until:Int) //提取从from到until的元素(不包含until)
val v: Array[T] = arr.init //提取除了最后一个元素以外的元素
val v: Array[T] = arr.tail //提取除了第一个元素以外的元素
val v: Iterator[Array[T]] = arr.inits //递归提取除了最后一个元素以外的元素
val v: Iterator[Array[T]] = arr.tails //递归提取除了第一个元素以外的元素
val v: Option[T] = arr.lift(index:Int) //提取指定下标位置的Option元素
val v: PartialFunction[T,T] = arr.orElse(pf:PartialFunction[T,B]) //下标越界根据偏函数规则提取元素,否则直接提取下标元素
详解:
applyOrElse
接收2个参数,参数1是调用的参数,参数2是回调函数,如果参数1调用的参数匹配,返回匹配的值,否则调用回调函数。
val arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val arrChar: Array[Char] = Array('a', 'b', 'c')
//参数1匹配
val v1: Int = arr.applyOrElse(1, { _: Int => 0 })
val v2: Char = arrChar.applyOrElse(1, {_:Int => 'z'})
println(v1) // 2
println(v2) // b
//参数1不匹配
val v1: Int = arr.applyOrElse(11, { _: Int => 0 })
val v2: Char = arrChar.applyOrElse(3, {_:Int => 'z'})
println(v1) // 0
println(v2) // z
takeWhile
从下标0开始取,碰到不满足条件p的就结束
val arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
var arrReverse: Array[Int] = Array(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
val array: Array[Int] = arr.takeWhile(_<5)
val array1: Array[Int] = arrReverse.takeWhile(_ <5)
array.foreach(print);println()
println("--------------")
array1.foreach(print)
//结果:
1234
--------------
//空行没数据
collect&collectFirst
collect:提取所有满足偏函数pf的元素
collectFirst:提取满足偏函数pf的第一个Option元素
val arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val v: Array[Int] = arr.collect({ case x if (x % 2 == 0) => x })
v.foreach(print) //246810
val v: Option[Int] = arr.collectFirst({ case x if (x % 2 == 0) => x })
println(v) //Some(2)
//偏函数:pf
//偶数不变,奇数变0
val pf:PartialFunction[Int,Int]={
case x if x%2==0 => x
case x if x%2!=0 => 0
}
val v: Array[Int] = arr.collect(pf)
v.foreach(print) //02040608010
inits&tailas
inits:递归提取除了最后一个元素以外的元素
tails:递归提取除了第一个元素以外的元素
val arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val v: Iterator[Array[Int]] = arr.inits
v.foreach(x=>{
x.foreach(print)
println()
})
//============
12345678910
123456789
12345678
1234567
123456
12345
1234
123
12
1
val v: Iterator[Array[Int]] = arr.tails
v.foreach(x=>{
x.foreach(print)
println()
})
//============
12345678910
2345678910
345678910
45678910
5678910
678910
78910
8910
910
10
orElse
下标越界根据偏函数规则提取元素,否则直接提取下标元素
val arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val p:PartialFunction[Int,Int] = (x:Int)=>x match {
case x if(x%2==0) => x
case _ => -1
}
val v: PartialFunction[Int, Int] = arr.orElse(p)
println(v(0)) // 1
println(v(1)) // 2
println(v(10)) // 10
println(v(11)) // -1
修改元素
val v:Unit = arr.update(index:Int, newValue:T) //修改指定index下标元素为newValue
val v: Array[T] = arr.updated(index:Int, newValue:T) //修改指定index下标元素为newValue,并生成新的数组返回
val v: Array[T] = arr ++/union sub //并集
val v: Array[T] = arr intersect sub //交集
val v: Array[T] = arr diff sub //差集
val v: Array[T] = arr :+ elem //尾部追加
val v: Array[T] = elem +: arr //头部追加
val v: Array[T] = arr.drop(size:Int) //删除头部size个元素
val v: Array[T] = arr.dropRight(size:Int) //删除尾部size个元素
val v: Array[T] = arr.dropWhile(p:T=>Boolean) //从左到右删除符合条件p的元素,碰到第一个不符合条件的元素停止
val v: Array[T] = arr.patch(from:Int,sub:GenSeq, replaceLen:Int) //从from开始的replaceLen个元素替换为sub中的全部元素
逐个迭代处理
val v: Array[B] = arr.map(f:T=>B) //对元素做f定义的操作,可以转变数据类型
val v: mutable.WrappedArray[T] = arr.transform(f:T) //对元素做f定义的操作,不可以转变数据类型
val v: Array[B] = arr.reverseMap(f:T=>B) //map+逆序
val v: Array[T] = arr.flatten //多维数组降一个维度
val v: Array[T] = arr.flatMap(f:T=>B) //map+flatten
分组
All:
val v: ParArray[T] = arr.par //分组并行
val v: (Array[T], Array[T]) = arr.partition(p:T=>Boolean) //根据条件p分区
val v: Map[K, Array[T]] = arr.groupBy(key:K) //根据key分组
val v: Iterator[Array[T]] = arr.grouped(size:Int) //按指定size个数分组
val v: Iterator[Array[T]] = arr.sliding(size:Int[,step:Int default 1]) //从第一个元素开始,每个元素和它后面的 size - 1 个元素组成一个数组
详解:
sliding
sliding(size: Int)
从第一个元素开始,每个元素和它后面的 size - 1 个元素组成一个数组,最终组成一个新的集合返回,当剩余元素不够 size 数,则停止
var arr = Array(1,2,3,4,5,6,7,8,9)
arr.sliding(3).foreach(arr=>{
arr.foreach(i=>print(s"${i}\t"))
println()
})
println("=============")
arr.sliding(4).foreach(arr=>{
arr.foreach(i=>print(s"${i}\t"))
println()
})
//结果:
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
=============
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9
sliding(size: Int, step: Int)
从第一个元素开始,每个元素和它后面的 size - 1 个元素组成一个数组,最终组成一个新的集合返回,当剩余元素不够 size 数,则停止,该方法,可以设置步进 step,第一个元素组合完后,下一个从 上一个元素位置+step后的位置处的元素开始
var arr = Array(1,2,3,4,5,6,7,8,9)
arr.sliding(3,1).foreach(arr=>{
arr.foreach(i=>print(s"${i}\t"))
println()
})
println("==============")
arr.sliding(3,3).foreach(arr=>{
arr.foreach(i=>print(s"${i}\t"))
println()
})
//结果:
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
==============
1 2 3
4 5 6
7 8 9
聚合
All:
val v: T = arr.reduce(f:(T,T)=>T) //从左向右对元素按f指定的操作进行聚合
val v: T = arr.reduceLeft(f:(T,T)=>T) //从左向右对元素按f指定的操作进行聚合
val v: T = arr.reduceLeftOption(f:(T,T)=>T) //从左向右对元素按f指定的操作进行聚合
val v: T = arr.reduceRight(f:(T,T)=>T) //从右向左对元素按f指定的操作进行聚合
val v: T = arr.reduceRightOption(f:(T,T)=>T) //从右向左对元素按f指定的操作进行聚合
val v: T = arr.fold[Left](beginValue:T)(f:(T,T)=>T) //从左向右根据定的初始值beginVlaue再对数组执行f指定的操作
val v: T = arr.foldRight(beginValue:T)(f:(T,T)=>T) //从右向左根据定的初始值beginVlaue再对数组执行f指定的操作
val v: Array[T] = arr.scan[left](beginValue:T)(f:(T,T)=>T) //从左向右根据定的初始值beginVlaue再对数组执行f指定的操作,返回每一步操作产生数据的数组
val v: Array[T] = arr.scanRight(beginValue:T)(f:(T,T)=>T) //从右向左根据定的初始值beginVlaue再对数组执行f指定的操作,返回每一步操作产生数据的数组
val v: T = arr.aggregate(beginValue:B)(map(B,T)=>B,reduce:(B,B)=>B) //根据定的初始值beginVlaue再对数组执行map和reduce
val v: T = arr.sum //求和
val v: Int = arr.count(p:Int=>Bollean) //根据p的条件计数
val v: T = arr.min //最小值
val v: T = arr.max //最大值
val v: Int = arr.minBy(_.?) => T:Tuple | Class //最小
val v: Int = arr.maxBy(_.?) => T:Tuple | Class //最大
详解:
reduce[Left][Option]/reduce[Right][Option]
//从左向右
val arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
println(arr.reduce(_ + _))
//结果
45
//内部过程
val add=(x:Int,y:Int)=>{
println(s"${x}+${y}=${x+y}")
x+y
}
println(arr.reduce(add))
//===================
1+2=3
3+3=6
6+4=10
10+5=15
15+6=21
21+7=28
28+8=36
36+9=45
45
//left/leftOption
val value:B = reduceLeft(f:(T,T)=>B)
val value:B = reduceLeftOption(f:(T,T)=>B)
//从右向左
println(arr.reduceRight(_ + _))
//内部过程
val add=(x:Int,y:Int)=>{
println(s"${x}+${y}=${x+y}")
x+y
}
println(arr.reduceRight(add))
//===================
8+9=17
7+17=24
6+24=30
5+30=35
4+35=39
3+39=42
2+42=44
1+44=45
45
//right/rightOption
val value:B = reduceRight(f:(T,T)=>B)
val value:B = reduceRightOption(f:(T,T)=>B)
fold & foldleft & foldright
fold:初始值顺序和每个元素运算,把得到的结果与下一个元素进行运算
foldleft:和fold一样,从左往右,初始值顺序和每个元素运算,把得到的结果与下一个元素进行运算
foldright:从左往右,初始值顺序和每个元素运算,把得到的结果与下一个元素进行运算
val cal = (a:Int,b:Int)=>{ println(s"${a}-${b}=${a-b}") a-b}println(arr.fold(0)(cal))println("-----------")println(arr.foldLeft(0)(cal))println("-----------")println(arr.foldRight(0)(cal))//结果:0-1=-1-1-2=-3-3-3=-6-6-4=-10-10-5=-15-15-6=-21-21-7=-28-28-8=-36-36-9=-45-45-----------0-1=-1-1-2=-3-3-3=-6-6-4=-10-10-5=-15-15-6=-21-21-7=-28-28-8=-36-36-9=-45-45-----------9-0=98-9=-17--1=86-8=-25--2=74-7=-33--3=62-6=-41--4=55
sacn[Left/Right]
用法同 fold,scan会把每一步的计算结果放到一个新的集合中返回,而 fold 返回的是单一的值
arr.scan(0)(cal).foreach(println)arr.scanLeft(0)(cal).foreach(println)arr.scanRight(0)(cal).foreach(println)
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
*/
验证
val v: Boolean = arr.isEmpty //判断是否为空
val v: Boolean = arr.nonEmpty //判断是否非空
val v: Boolean = arr.exists(p:T=>Boolean) //是否存在符合条件p的元素
val v: Boolean = arr.contains(elem:T) //是否存在给定元素
val v: Boolean = arr.containsSlice(sub:GenSeq) //是否存在完整的子串
val v: Boolean = arr.forall(p:T=>Boolean) //是否所有元素都符合条件p
val v: Boolean = arr.corresponds(sub:GenSeq)(p:T=>Boolean) //是否sub中所有元素和主集合的元素满足关系p
val v: Boolean = arr.sameElements(sub:GenSeq) //集合和子集是否拥有相同元素
val v: Boolean = arr.startsWith(sub:GenSeq) //集合是否以sub开头
val v: Boolean = arr.endWith(sub:GenSeq) //集合是否以sub结尾
长度
val v: Int = arr.length/Size //求集合长度
val v: Int = arr.prefixLength(p:T=>Boolean) //从左开始,连续满足条件p的连续元素长度
val v: Int = arr.segmentLength(p:T=>Boolean,index:Int) //从指定下标位置index开始,连续满足条件p的元素长度
val v: Int = arr.lengthCompare(len:Int) //返回集合长度和给定长度len的差值
转变
All:
arr.copyToArray(copy) //将arr中的元素复制到copy中,长度有限制
arr.copyToBuffer(copy) //将arr中的元素复制到copy中,长度无限制
val v: Array[T] = arr.toArray //将arr转化为Array数组
val v: mutable.Buffer[T] = arr.toBuffer //转化为Buffer类型
val v: Array[T] = arr.array //获取集合副本
val v: Array[T] = arr.clone() //获取集合副本
val v: mutable.IndexedSeq[T] = arr.deep //获取集合副本
val v: mutable.WrappedArray[T] = arr.repr //获取集合副本
val v: mutable.IndexedSeq[T] = arr.seq //获取集合副本
val v: Map[K,V] = arr.toMap //转化为Map
val v: Set[T] = arr.toSet //去重复
val v: Iterator[T] = arr.toIterator //一次迭代
val v: Stream[T] = arr.toStream //不定数量元素遍历(懒加载)
val v: Array[T] = arr.padTo(len:Int, elem:T) //新生成一个长度为len的数组,空余位置默认值为elem
val v: (Array[T], Array[T]) = arr.span(p:Int=>Boolean) //从左到右至第一个不满足条件p的元素结束作为一个数组,剩余元素作为另一个数组,两个数组包装成元祖返回
val v: (Array[T], Array[T]) = arr.splitAt(index:Int) //根据给定的index位置,分为两个数组,包装成元祖返回
val v: Array[Array[T]] = arr.transpose //矩阵转置
val v: Array[(T, T)] = arr1.zip(arr2) //将两个集合相同位置的下的两个元素组合成Tuple2,并返回成元祖,多余的长度会被忽略
val v: Array[(T, T)] = arr1.zipAll(arr2,this,that) //将两个集合相同位置的下的两个元素组合成Tuple2,并返回成元祖,不足自动填充,this填充元祖_1的值,that填充元祖_2的值
val v: (Array[T], Array[T]) = arr.unzip //将含有两个元素的数组,第一个元素取出组成一个序列,第二个元素组成一个序列
val v: (Array[T], Array[T], Array[T]) = arr.unzip3 //将含有三个元素的数组,对应位置的元素单独抽离分别包装成三个数组,并将三个数组包装成元祖返回
val v: Array[(T, T)] = arr.zipWithIndex //序列中的每个元素和它的索引组成一个序列
详解:
array,clone(),deep,repr,seq的区别
//array是原数组的引用
val arr2: Array[Int] = arr1.array
println(arr2 == arr1)
println(arr2.equals(arr1))
println(arr2 != arr1)
println(arr2 ne arr1)
//结果:
true
true
//clone()新生成了一个数组
val arr3: Array[Int] = arr1.clone()
println(arr3 == arr1)
println(arr3.equals(arr1))
//结果:
false
false
//deep同clone()
val arr4: IndexedSeq[Any] = arr1.deep
println(arr4 == arr1)
println(arr4.equals(arr1))
//结果:
false
false
//repr同array
val arr5 = arr1.repr
println(arr5 == arr1)
println(arr5.equals(arr1))
//结果:
true
true
//seq
val arr6: mutable.IndexedSeq[Int] = arr1.seq
println(arr6 == arr1)
println(arr6.equals(arr1))
//结果:
false
false
toMap
转换成map类型
var rng = Array(("xiaohu", 23), ("mlxg", 11), ("midhu", 19), ("uzi", 23), ("ming", 22))
val map = rng.toMap
map.keySet.foreach(println)
map.values.foreach(println)
//结果
midhu
xiaohu
mlxg
uzi
ming
19
23
11
23
22
padTo
填充补齐序列
//如果当前序列长度小于 len,那么新产生的序列长度是 len,多出的几个位值填充 elem,如果当前序列大于等于 len ,则返回当前序列
-def padTo(len: Int, elem: A): Array[A]
val a = Array(1, 2, 3, 4, 5)
val b = a.padTo(7,9) //需要一个长度为 7 的新序列,空出的填充 9
println(b.mkString(",")) //1,2,3,4,5,9,9
span/splitAt
分割一个序列为两个
//分割序列为两个集合,从第一个元素开始,直到找到第一个不满足条件的元素止,之前的元素放到第一个集合,其它的放到第二个集合
-def span(p: (T) ⇒ Boolean): (Array[T], Array[T])
val a = Array(3,2,1,4,5)
val b = a.span( {x:Int => x > 2})
println(b._1.mkString(",")) // 3
println(b._2.mkString(",")) // 2,1,4,5
//从指定位置开始,把序列拆分成两个集合
-def splitAt(n: Int): (Array[T], Array[T])
val a = Array(3,2,1,4,5)
val b = a.splitAt(2)
println(b._1.mkString(",")) // 3,2
println(b._2.mkString(",")) // 1,4,5
transpose
二维矩阵转置
val chars = Array(Array("a","b"),Array("c","d"),Array("e","f"))
val v: Array[Array[String]] = chars.transpose
v.foreach(x=>{
x.foreach(print)
println()
})
//
ace
bdf
zip/zipAll/unzip/zipWithIndex
数组组合
//将两个序列对应位置上的元素组成一个pair序列
-def zip[B](that: GenIterable[B]): Array[(A, B)]
val a = Array(1,2,3,4,5)
val b = Array(5,4,3,2,1)
val c = a.zip(b)
println(c.mkString(",")) //(1,5),(2,4),(3,3),(4,2),(5,1)
//同zip,但是允许两个序列长度不一样,不足的自动填充,如果当前序列端,空出的填充为 thisElem,如果 that 短,填充为 thatElem
-def zipAll[B](that: collection.Iterable[B], thisElem: A, thatElem: B): Array[(A, B)]
val a = Array(1,2,3,4,5,6,7)
val b = Array(5,4,3,2,1)
val c = a.zipAll(b,9,8) //(1,5),(2,4),(3,3),(4,2),(5,1),(6,8),(7,8)
val a = Array(1,2,3,4)
val b = Array(5,4,3,2,1)
val c = a.zipAll(b,9,8) //(1,5),(2,4),(3,3),(4,2),(9,1)
//将含有两个元素的数组,第一个元素取出组成一个序列,第二个元素组成一个序列
-def unzip[T1, T2](implicit asPair: (T) ⇒ (T1, T2), ct1: ClassTag[T1], ct2: ClassTag[T2]): (Array[T1], Array[T2])
val chars = Array(("a","b"),("c","d"))
val b = chars.unzip
println(b._1.mkString(",")) //a,c
println(b._2.mkString(",")) //b,d
//序列中的每个元素和它的索引组成一个序列
-def zipWithIndex: Array[(A, Int)]
val a = Array(10,20,30,40)
val b = a.zipWithIndex
println(b.mkString(",")) //(10,0),(20,1),(30,2),(40,3)
排序
val v: Array[T] = arr.reverse //逆序
val v: Iterator[T] = arr.reverseIterator //逆序迭代器
val v: Array[T] = arr.sorted //升序
val v: Array[T] = arrReverse.sortBy(f:T=>B) //x=>x 升序 | x=>-x 降序
val v: Array[T] = arr.sortWith(f:(T,T)=>Boolean) //_<_ 升序 | _>_ 降序
字符串拼接
All:
addString
拼接字符串
val builder = new StringBuilder
//将数组中的元素逐个添加到builder
val str = arr1.addString(builder)
//每个元素用sep分隔符分开
val str1 = arr1.addString(builder, ",")
//在首尾各加一个字符串,并指定sep分隔符
val str2 = arr1.addString(builder, "{", ",", "}")
mkString
单集合拼接
//将数组中的元素逐个添加
println(arr1.mkString)
//每个元素用sep分隔符分开
println(arr1.mkString(","))
//在首尾各加一个字符串,并指定sep分隔符
println(arr1.mkString("{", ",", "}"))
//结果:
2456
2,4,5,6
{2,4,5,6}
根据值获取下标
val v: Int = arr.indexOf(v:T[,start:Int]) //从左向右,获取[从start位置开始]第一个为v的值的下标
val v: Int = arr.indexOfSlice(sub:GenSeq[,start:Int]) //从左向右,获取集合中第一个连续等于sub子序列值的首元素下标
val v: Int = arr.indexWhere(p:T=>Boolean[,start:Int]) //从左向右,获取集合中第一个符合参数函数条件p的下标
val v: Int = arr.lastIndexOf(v:T[,start:Int]) //从右向左,获取[从start位置开始]第一个为v的值的下标
val v: Int = arr.lastIndexOfSlice(sub:GenSeq[,start:Int]) //从右向左,获取集合中第一个连续等于sub子序列值的首元素下标
val v: Int = arr.lastIndexOfWhere(p:T=>Boolean[,start:Int]) //从右向左,获取集合中第一个符合参数函数条件p的下标
val v: Range = arr.indices //返回当前序列索引集合