Scala 经常遇到需要去重和取交集的情况,这里对Set简单使用和性能进行分析:
val a = Set(1,2,3)
val b = Set(2,3,4)
1.交集
println(a & b)
println(a intersect(b))
2.并集
println(a ++ b)
println(a | b)
println(a.union(b))
3.差集
差集需要注意前后顺序的区别,会造成最终结果的不同,前面交集和并集不守影响
4.增加删除元素
A.直接调用api
a.add(9)
a.remove(10)
B.直接加减 需要注意类型一致
println(a + (1,9))
println(a - (1,9))
C.这里需要注意的是++= 和 ++ , --= 和--有区别,++=和--=会影响原始集合,++和--则不会影响原始集合,只执行当次操作
println(a ++ b)
println(a)
println(a ++= b)
println(a)
Set(1, 2, 3, 4)
Set(1, 2, 3)
Set(1, 2, 3, 4)
Set(1, 2, 3, 4)
5.Set性能分析
大量数据去重情况下,先聚合所有数据再去重,还是逐条去重
A.先定义一个生成Array的函数:
def genArr(): Array[Int] = {
val tmp = new ArrayBuffer[Int]()
for (i <- 0 to 5){
tmp.append(scala.util.Random.nextInt(10000))
}
tmp.toArray
}
B.逐条去重
val st1 = System.currentTimeMillis()
var featSet: Set[Int] = Set()
for (i <- 0 to 10000) {
featSet ++= genArr().toSet
}
println(featSet)
val st2 = System.currentTimeMillis()
C.先聚合再去重
val st3 = System.currentTimeMillis()
var featArr = new ArrayBuffer[Int]()
for (i <- 0 to 10000) {
featArr ++= genArr()
}
print(featArr.toArray.toSet)
val st4 = System.currentTimeMillis()
D.查看时间
10条数据时:
逐条处理 37
聚合再处理 1
10000条数据时:
逐条处理 338
聚合再处理 40
Tip:本地测试两次都是先聚合再处理的速度快,不过在生产环境中也遇到过相反的情况,总的来说,数据比较少或者占内存小,一般情况先聚合再生成set的效率高一些;数据很大,或者本机内存不足时,逐条处理效率会略优于先聚合在处理