集:Set
-
基本介绍:
scala中默认使用不可变集合,若要使用可变集合,需要引用 scala.collection.mutable.Set 包;
Set中元素无序不重复; -
创建:
①val set = Set(1, 2, 3) //不可变
②val mutableSet = mutable.Set(1, 2, 3) //可变
-
添加:
mutableSet.add(4) //方式1 mutableSet += 6 //方式2 mutableSet.+=(5) //方式3 //注:如果添加的对象已经存在,则不会重复添加,也不会报错
-
删除:
val set = mutable.Set(1,2,4,"abc") set -= 2 // 操作符形式 set.remove("abc") // 方法的形式,scala的Set可以直接删除值 /注:如果删除的对象不存在,则不生效,也不会报错
-
遍历:
for(i <- set) println(i)
集合元素的操作
- map映射
-
将集合的每一个元素通过指定功能(函数)映射(转换)成新的结果集(将一个函数作为参数传给另一个函数,这就是函数式编程的特点)
-
快速入门案例:
//将List(3,5,7) 中的所有元素都 * 2 ,
//将其结果放到一个新的集合中返回,即返回一个新的List(6,10,14)
-
代码实现:
val list1 = List(3,5,7) def fun(n: Int):Int={ 2*n } val list2 = list1.map(fun)
-
高阶函数的基本使用案例:
def main(args: Array[String]): Unit = { val res = test(fun,6) println(res) } def test(f:Double => Double,d:Double): Double ={ fun(d)*2 } def fun(d:Double): Double ={ d*d }
-
map映射函数的机制-模拟实现:
-
class MyList {
var list1 = List(3, 5, 7)
var list2 = List[Int]()
def map(f:Int => Int): List[Int] = {
for (item<-list1) {
list2 = list2 :+ f(item)
}
list2
}
}
object MyList {
def apply(): MyList = new MyList()
}
def main(args: Array[String]): Unit = {
val list1 = List(3, 5, 7)
def f1(n1: Int): Int = {
println("xxx")
2 * n1
}
val list2 = list1.map(f1)
println(list2)
val myList = MyList()
val res= myList.map(f1)
println("res=" + res)
println("myList=" + myList.list1)
}
- flatmap映射
- 基本介绍:flat即压扁,压平,扁平化,效果就是将集合中的每个元素的子元素映射到某个函数 中并返回新的集合
- 案例:
def main(args: Array[String]): Unit = {
val names = List("Alice", "Bob", "Nick")
def upper(str: String): String = {
str.toUpperCase
}
val res = names.flatMap(upper)
println(res)//输出 List(A, L, I, C, E, B, O, B, N, I, C, K)
}
- filter:过滤元素
- 基本介绍:将符合要求的数据(筛选)到新的集合中
- 案例:将 val names = List(“Alice”, “Curry”, “Nick”) 集合中首字母为’C’的筛选到新的集合
val names = List("Alice", "Curry", "Nick")
def fun(str: String): Boolean = {
str.startsWith("C")
}
val res = names.filter(fun)
println(res)//输出List(Curry)
-
化简
- 基本介绍:将二元函数引用到集于集合中的函数(reduceLeft、reduceRight、reduce)
- 案例1:val list = List(1, 20, 30, 4 ,5) , 求出list的和.
val list = List(1, 20, 30, 4 ,5) def sun(a: Int,b: Int):Int = a + b val res = list.reduceLeft(sun)// ((((1+20)+30)+4)+5) println(res1)// 60
- 案例2:
val list1 = List(1, 2, 3, 4, 5) def fun2(a: Int, b: Int):Int = a-b val x1 = list1.reduceLeft(fun2)//((((1-2)-3)-4)-5) val x2 = list1.reduceRight(fun2)//(1-(2-(3-(4-5)))) val x3 = list1.reduce(fun2)//同reduceLeft println(x1) // -13 println(x2) // 3 println(x3) // -13
- 案例3:使用化简的方法求出(3,4,2,7,0,5,1)中的最小值
val list = List(3,4,2,7,0,5,1) def getMin(n1:Int,n2: Int):Int = if(n1 >= n2) n2 else n1 val res1 = list.reduce(getMin) println(res1)
-
折叠
- 基本介绍:fold函数将上一步返回的值作为函数的第一个参数继续参与运算,直到list中所有的值被遍历(可以把reduceLeft看做简化版的foldLeft);
- 案例1 (foldLeft和foldRight的缩写方法分别是: /: 和 :\ )
val list1 = List(1,2,3,4) def fun(n1: Int,n2: Int):Int = n1 - n2 val res2 = (6/:list)(fun)//函数的柯里化 val res3 = (list:\6)(fun) val res4 = list1.fold(6)(fun) println(res2) println(res3) println(res4)
-
扫描
- 基本介绍:扫描,即对集合中的每个元素做fold操作,但是会把所有产生的中间结果放置在一个集合中保存;
- 实例:
def fun(a: Int,b: Int):Int = a - b val res = (1 to 5).scanLeft(5)(fun) println(res)//(1,2,3,4,5)=>(5,4,2,-1,-5,-10) def fun2(a: Int,b: Int): Int = a + b val res2 = (1 to 5).scanLeft(5)(add) println(res2)//(1,2,3,4,5)=>(5,6,8,11,15,20)
-
WordCount案例:
def wordCount():List[(String,Int)] = {
List("java java spark","hdfs spark kafka spark")
.flatMap(_.split(" "))//List(java, java, spark, hdfs, spark, kafka, spark)
.map((_,1))//List((java,1), (java,1), (spark,1), (hdfs,1), (spark,1), (kafka,1), (spark,1))
.groupBy(_._1)//Map(spark -> List((spark,1), (spark,1), (spark,1)), hdfs -> List((hdfs,1)), java -> List((java,1), (java,1)), kafka -> List((kafka,1)))
.map(x => (x._1,x._2.size))//Map(spark -> 3, hdfs -> 1, java -> 2, kafka -> 1)
.toList.sortBy(_._2)//List((hdfs,1), (kafka,1), (java,2), (spark,3))
}