一、scala简介
Scala是一门运行在JVM上的多范式的编程语言,一种类似java的编程语言,设计初衷是实现可伸缩的语言、并集成面向对象编程和函数式编程的各种特性。被应用于spark、flink开发。
二、基本语法
1、变量定义
val name ="zhangsan" //val定义的变量不可被重新赋值 var name ="lisi" //惰性赋值 lazy val name ="zhangsan" //用到时才会加载到内存
2、变量表达式
//数据类型,与java类似,注:scala中所有类型都是大写字母开头 val name ="zhangsan" val info =s"${name},你好!!" //使用三个""" """内的内容都会被解释为字符串
3、条件表达式
在scala中条件表达式也是有返回值的,没有三元表达式
1>、if表达式
val sex="zhangsan" val result=if(sex=="zhangsan") 1 else 0
2>、for、while表达式
val nums = 1.to(10) //定义1到10的数据集 for(i<-nums)print(i) //循环打印1到10的数字 //守卫 for表达式中可以添加if判断,这个if判断就称为守卫 for(i<- 1 to 10 if i%3==0)println(i) //打印1到10内能被3整除的数 //for推导式 /**在for循环体中,可以使用yield表达式构建出一个集合,我们把使用yield的for表达式称之为推导式*/ val v = for(i <- 1 to 10) yield i * 10 //用1到10的集合构建,(10,20,30....)的新集合
//while循环和java一样
4、break和continue
/**注:在scala中,类似Java和C++的break/continue关键字被移除了,如果一定要使用break/continue,就需要使用scala.util.control包的Break类的breable和break方法。*/ //break实现(breakable包for的整个表达式) import scala.util.control.Breaks._ //导入Breaks包 breakable{ for(i <- 1 to 100) { if(i >= 50) break() else println(i) } } //使用for表达式打印1-100的数字,如果数字到达50,退出for表达式 //continue实现(breakable包for表达式的循环体) import scala.util.control.Breaks._ for(i <- 1 to 100 ) { breakable{ if(i % 10 == 0) break() else println(i) } } //打印1-100的数字,使用for表达式来遍历,如果数字能整除10,不打印
5、方法
def add(a:Int, b:Int) = a + b //实现两个整数相加和,注:参数列表的参数类型不能省略,返回值可以不写return,默认就是{}块表达式的值,返回值类型可以省略,除递归方法外 //正确写法 def m2(x:Int):Int={ if(x<=1) 1 else m2(x-1)*x } //错误写法 def m2(x:Int)={ if(x<=1) 1 else m2(x-1)*x } //方法参数 def add(x:Int = 0, y:Int = 0) = x + y add() //默认参数 add(x=1) //带名参数 def add(num:Int) = num.sum add(1,2,3,4,5) //变长参数,计算1,2,3,4,5的和 //方法调用方式 Math.abs(-1) //后缀调用法,返回-1的绝对值 Math abs -1 //中缀调用法,返回-1的绝对值 Math.abs{-1} //花括号调用法,返回-1的绝对值 def m3()=println("hello") m3 //无括号调用法
6、函数
val add = (x:Int, y:Int) => x + y //方法函数的区别 /**1、方法是隶属于类或者对象的,在运行时会加载到JVM的方法区中 2、可以将函数对象赋值给一个变量,在运行时,它是加载到JVM的堆内存中 3、函数是一个对象,继承自FunctionN,函数对象有apply,curried,toString,tupled这些方法。方法则没有*/ //方法转换为函数 def add(x:Int,y:Int)=x+y val a = add _ //使用_即可将方法转换为函数
7、数组
val a = Array("java", "scala", "python") //定长数组 import scala.collection.mutable.ArrayBuffer val a = ArrayBuffer("hadoop", "storm", "spark") //变长数组,需引入ArrayBuffer的类,使用+=添加元素,使用-=删除元素,使用++=追加一个数组到变长数组 //遍历数组 val a = Array(1,2,3,4,5) for(i<-a) println(i) //for表达式直接遍历 for(i <- 0 to a.length - 1) println(a(i)) //使用for表达式基于索引下标遍历 /**注: 0 until n——生成一系列的数字,包含0,不包含n 0 to n ——包含0,也包含n*/ //数组的常用算法 val a = Array(1,2,3,4) a.sum //求和 a.max //最大值 a.min //最小值 a.sorted //升序 a.sorted.reverse //降序
8、元组
//元组可以用来包含一组不同类型的值。例如:id,姓名,年龄,地址。元组的元素是不可变的 val a = (1, "zhangsan", 20, "beijing") val a = ("zhangsan", 20) //使用括号定义元组 val a = "zhangsan" -> 20 //使用箭头定义元组 //访问元组 a._1 //元组的第一个元素 a._2 //元组的第二个元素
9、列表(可以保存重复的值,有先后顺序)
//不可变列表,元素,长度均不可变 val a = List(1,2,3,4) val a = Nil //不可变得空列表 val a = -2 :: -1 :: Nil //使用::方法创建列表 //可变列表,元素长度均可变 import scala.collection.mutable.ListBuffer //导入依赖的包 val a = ListBuffer[Int]() //定义空列表 val a = ListBuffer(1,2,3,4) //获取元素(使用括号访问(索引值)),添加元素(+=),追加一个列表(++=),更改元素(使用括号获取元素,然后进行赋值),删除元素(-=),转换为List(toList),转换为Array(toArray) //列表常用操作 val a = List(1,2,3,4) val b = List(4,5,6) a.isEmpty //判断列表是否为空 a ++ b //拼接两个列表 a.head //获取列表的首个元素 a.tail //获取列表的剩余部分 a.reverse //反转列表 a.take(3) //列表前缀(前三个元素) a.drop(3) //列表后缀(除前三个元素) val a = List(List(1,2), List(3), List(4,5)) a.flatten //扁平化(将列表中的列表中的所有元素放到一个新列表中List(1,2,3,4,5)) val a = List("zhangsan", "lisi", "wangwu") val b = List(19, 20, 21) val c = a.zip(b) //拉链List((zhangsan,19), (lisi,20), (wangwu,21)) c.unzip //拉开(List(zhangsan, lisi, wangwu),List(19, 20, 21)) val a = List(1,2,3,4) println(a.toString) //转换字符串"""List(1, 2, 3, 4)""" a.mkString(":") //生成字符串1:2:3:4 val a1 = List(1,2,3,4) val a2 = List(3,4,5,6) a1.union(a2) //并集 a1.union(a2).distinct //并集调用distinct去重 a1.intersect(a2) //交集 a1.diff(a2) //差集
10、集合(元素不重复,无序)
val a = Set(1,1,3,2,4,8) //不可变集合 //基本操作 val a = Set(1,1,3,2,4,8) a.size //获取集合大小 for(i <- a) println(i) //遍历集合 a - 1 //删除一个元素 a ++ Set(6,7,8) //拼接两个集合 a ++ List(6,7,8,9) //拼接集合和列表
//注:可变列表需带入此包import scala.collection.mutable.Set
11、映射
val map = Map("zhangsan"->30, "lisi"->40) //基本操作 val map = Map("zhangsan"->30, "lisi"->40) map("zhangsan") //获取指定key的值 map.keys //获取所有的key map.values //获取所有的值 for((x,y) <- map) println(s"$x $y") //遍历map集合 map.getOrElse("wangwu", -1) //判断指定key是否存在,不存在返回-1 map + "wangwu"->35 //增加一个键值对 map - "lisi" //删除指定key及值
12、迭代器iterator
val a = List(1,2,3,4,5) val ite = a.iterator while(ite.hasNext) { println(ite.next) } //while迭代遍历并打印列表 for(i <- a) println(i) //for遍历打印列表
三、函数式编程
后面Spark/Flink的大量业务代码都会用到函数式编程
val a = List(1,2,3,4) //遍历 a.foreach(x=>println(x)) //foreach遍历 a.foreach(println(_)) //foreach下划线简写遍历 //映射 a.map(x=>x+1) //映射List(2,3,4,5) a.map(_ + 1) //下划线式映射List(2,3,4,5) val a = List("hadoop hive spark flink flume", "kudu hbase sqoop storm") //扁平化映射 a.map(x=>x.split(" ")) //按照空格切割映射为新的列表List(Array(hadoop, hive, spark, flink, flume), Array(kudu, hbase, sqoop, storm)) a.map(x=>x.split(" ")).flatten //映射并扁平化List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm) a.flatMap(_.split(" ")) //扁平化映射,相当于上一条List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm) val a = List(1,2,3,4) //过滤 a.filter(_ % 2 == 0) //过滤能被2整除的,List(2,4) //排序 List(3,1,2,9,7).sorted //默认排序 val a = List("01 hadoop", "02 flume", "03 hive", "04 spark") a.sortBy(_.split(" ")(1)) //指定字段排序{将列表内元素按照空格切分,并指定切分后的第二个元素排序,即按照单词字母排序List(02 flume, 01 hadoop, 03 hive, 04 spark)} val a = List(2,3,1,6,4,5) a.sortWith((x,y) => if(x<y)true else false) //sortWith自定义排序 a.sortWith(_ < _).reverse //sortWith自定义排序简写 val a = List("张三"->"男", "李四"->"女", "王五"->"男") //分组 a.groupBy(_._2) //按照性别分组 val a = List(1,2,3,4,5,6,7,8,9,10) //聚合 a.reduce((x,y) => x + y) //聚合 a.reduceLeft(_ + _) //从左往右聚合 a.reduceRight(_ + _) //从右往左聚合 a.fold(0)(_ + _) //同reduce一样,但须指定初始值参数(foldRight表示从右往左计算,foldRight表示从右往左计算)