scala
开发spark可以使用哪些语言:
Python开发45%
scala 35%
java 20% 一、scala的概述
java基础上代码的简化版、功能的加强版
隐式转换
高阶函数
一个函数的参数是另一个函数 ,或者是返回值是一个函数
1、scala继承了面向对象编程和面向函数式编程的各种特征,在2003年发布了基础java的第一个版本
Object-Oriented Meets Functional scala 优雅 简洁 强大 基于spark的开发使用scala语言实现wordcount sc.textFile("/user/beifeng/input/wc.txt") //RDD[String]
.flatMap(x=>x.split(" ")) // Array[(String)]
.map(x=>(x,1)) //Array[(String,Int)]
.reduceByKey((x,y)=>(x+y)) //Array[(String,Int)]
.saveAs("/user/beifeng/output1") hadoop hive hive spark
oozie flume
Array(hadoop hive hive spark oozie flume )
Array[(hadoop,1), (hive,1), hive spark oozie flume ] 2、scala和java可以互操作
java和scala共用jvm平台
scala使用scalac编译器将源码编译成java的class文件
可以在scala代码中直接调用所有的java类库
也可以在java的代码中插入一段scala代码
3、函数式链式编程一些以函数和对象两方面为主
函数在scala中是一等公民
函数可以被当做参数进行传递
函数可以做为一个函数的返回值返回
可以在函数中定义另一函数 重点:
模式匹配
高阶函数
匿名函数
隐式转换
将一种数据类型偷偷转换成另一种数据类型
trait类
接口 二、scala安装部署 下载路径:http://www.scala-lang.org/download/2.10.4.html
window下:
java需求提前配置好
scala配置:
scala-2.10.4.zip 解压到某个路径下
配置环境变量:
JAVA_HOME XXX
SCALA_HOME XXX
PATH %JAVA_HOME%/bin;%SCALA_HOME%/bin
linux: 三、scala基本使用 交互式命令行 -》 REPl l->loop scala是一种强类型语言
但是scala可以自动推断数据类型
scala> val b = 3
b: Int = 3 scala> b+5
res0: Int = 8 //res0是系统提供的临时变量 scala> res0+1
res1: Int = 9 scala> println("hello world")
hello world scala写第一个程序 object HelloWorld {
def main(args:Array[String]) {
println("Hello,world!!!")
}
} $ scalac HelloWorld.scala
$ scala HelloWorld 四、安装部署IDEA工具 window/linux 版本
window:
安装前一定要配置好scala和java的环境变量
启动-》选择主题-》都是下一步(不要选择任何插件)-》start
集成scala插件:
configure-》plugins-》install form disk -》选择scala插件-》重启
Setting:
appreance-》设置系统字体及主题
keymap -》 设置快捷键风格-》eclipse
editor->font->save as -> 设置代码字体风格 create new project
scala -》设置项目名称及工程目录 -》选择本地安装的jdk的sdk 五、scala中变量的定义、数据类型、函数的定义及函数的参数类型 1、变量的定义
使用val声明一个不可变变量
scala> val a:Int=3
a: Int = 3
scala> a=4 //val声明的变量不能重新赋值
<console>:8: error: reassignment to val
a=4
^
使用var声明一个可变变量
scala> var c = 6
c: Int = 6 scala> c = 7
c: Int = 7 在scala中声明变量的语法
val/var a:Int=3
语法:
关键字(val/var)+ 变量名:数据类型(首写字母大写) = 值 2、scala中如何先定义一个为空值的变量
scala> var name:String //报错,需要给变量一个初始化值
解决:
scala> var name:String = ""
scala> var name1:String = _ 3、scala中的数据类型
在scala中没有基本数据量和包装类之分,所有的数据类型都是类
首写字母需要大写 4、scala中的lazy 懒执行
当val修饰的变量被lazy修饰时,它的初始化将被推迟,直到第一次去调用
scala> lazy val price = 15.8
price: Double = <lazy> //此时没有将15.8赋值给price scala> price //当第一次去调用 price时系统才会进行赋值操作
res3: Double = 15.8 scala> lazy var price1 = 15.8
<console>:1: error: lazy not allowed here. Only vals can be lazy
lazy var price1 = 15.8
^
5、scala中函数的定义 def 函数名称(参数名称:参数类型):返回类型 = {
函数体内容
} 因为scala可以自动推断数据类型,所以函数的返回值类型一般可以直接省略 def min(x:Int,y:Int):Int = { if (x>y)
y
else
x } 6、文件编辑软件sublime介绍
查看-》语法-》scala 7、当定义的函数为空参时,调用该函数时可以省略函数的括号
def hello()={println("hello!!!")}
def hello() = println("hello!!!") //当函数体只有一句时可以省略大括号
hello()
hello def hello():Unit = println("hello!!!")
Unit在scala中表示无返回值类型,相当于java的void 8、函数中定义另一个函数
函数的嵌套或闭包
内函数可以调用外函数的变量 def fun1(a: Int) = {
def fun2(b: Int) = {
println("a+b=" + (a + b))
}
fun2(200)
} fun1(20) scala> :paste //进入到粘贴模式 (ctrl-D to finish) scala> fun1(100)
a+b=300 9、匿名函数 定义: (x:Int)=>{x+1}
语法:(变量名:数据类型,...)=> { 函数体内容 } 匿名函数的特点: 1、匿名函数可以赋值给一个函数
def add=(x:Int,y:Int)=>{x+y}
add(3,8)
2、匿名函数可以赋值给一个变量
val add=(x:Int,y:Int)=>{x+y}
add(3,6) 考虑如何将一个非匿名函数赋值给一个变量 ?
def add(x: Int, y: Int) = x + y
val add1=add _ //函数名+空格+占位符
add1(3,8) 10、在scala的函数中可以指定参数的默认值(缺省值) def path(p: String="Desttop") = {
println("the path is " + p)
} path() //当传入参数时,会使用参数的默认值 def loadConf(conf:String="spark-defalut.xml")={
println("conf is "+conf )
}
11、scala中可以使用*代表传入的参数为重复参数(变长参数) def printName(name:String*)={
println("the name is "+name)
}
printName("zhangsan","lili","wangwu") val arr=Array("lili","tom","mary") printName(arr:_*)//通过声明arr为_*,表示告诉编译器我们传入的是一个个String类型的元素,而不是一个Array[String] 六、scala中的流程控制语句及循环表达式
while
do while
for
breaks 1、
val list=List("tom","mary","lio","lili") //定义一个List集合不用使用new,使用的是List类的伴生对象里面的apply方法,通过apply方法帮我们new的List对象 val list = List("tom", "mary", "lio", "lili") var x = 0
while (x < list.length) {
println(list(x))
x += 1
} for (x <- list) {
println(x)
} “<-”是一个提取符,可以从集合中遍历提取出所有的元素 break() 方法演示 object LoopTest {
def main(args: Array[String]) {
val list = List("tom", "mary", "lio", "lili")
val loop = new Breaks loop.breakable { for (x <- list) {
println(x)
if (x == "mary")
loop.break()
}
}
println("over........") }
} ----------------------------------- 2、scala中的循环表达式 1 to 10 //包头包尾
1.to(10) 1 until 10 //包头不包尾
1.until(10) Range(1,10) //包头不包尾 Range(1,-10,-3) //可以给出step步长
Range(1,-10,0) //java.lang.IllegalArgumentException: step cannot be 0. 结合for循环使用循环表达式 for (x<- 1.to(10)){
println(x)
} 求1到10范围内的偶数 for (x<- 1.to(10) if x%2==0 ){
println(x)
} 七、元组 tuple 元组的定义 使用 括号 ()
val tuple = (1, 3, "tom", 3.3, "lili") tuple._1 //元组元素的获取
tuple._3 总结 :
元组类型是scala和Python里特有
在scala中,元组是n个不同数据类型对象的一个聚集
n的最大的值是22
Map的元素实际上是n=2的元组 ,即2元组 ,也是最简单的元组
元组必须使用()来表示 元组元素的遍历 val tuple = (1, 3, "tom", 3.3, "lili")
for (x<- 0 to tuple.productArity ) { //使用to为什么会报错
println(tuple.productElement(x))
} for (x<- 0 until tuple.productArity ) { // until不报错
println(tuple.productElement(x))
} 八、scala中的数组
1、scala中数组的特点
数组是相同数据类型固定大小的元素的连续集合
数组的元素的角标从0开始 数组的定义
val arr=Array(33,11,66,88) 2、数组分为定长数组和变长数组 定长数组
val arr=Array(33,11,66,88) //默认是定长数组 数组的取值
arr(0)
arr(2)
定长数组不支持更改数组元素长度或值的方法 变长数组
val arr1=scala.collection.mutable.ArrayBuffer(11,22,44) import scala.collection.mutable.ArrayBuffer
val arr2=ArrayBuffer(55,99) 添加元素
val arr1 = scala.collection.mutable.ArrayBuffer(11, 22, 44)
val arr = Array(111, 222)
arr1 += 55
arr1
arr1 +=(66, 77)
arr1 ++= arr
减去元素
-=/--= 变长数组可以使用的更改元素内容的方法
arr1.insert(0,77,88)
arr1 arr1.remove(3)
arr1 arr1.trimEnd(2)
arr1 arr1.toArray //变长数组转定长数组 3、数组的遍历 for (x <- 0 until arr1.length) {
println(arr1(x))
} for (x <-arr1){
println(x)
} 4、其他常用方法 排序:
val arr1 = scala.collection.mutable.ArrayBuffer(55,11, 22, 44)
val arr2=arr1.toArray
scala.util.Sorting.quickSort(arr2) //原来的数组变了
arr2 arr1.sorted //默认是升序排序,返回一个新的排好序的数组 ,原来的不变 转换为字符串
arr1.mkString(",")
arr1.mkString("【",",","】") //res1: String = 【55,11,22,44】 九、scala中的集合 scala中所有的集合类都在 scala.collection 包下
scala.collection.mutable 包下是可变集合
可变集合可以进行修改、添加、删除等操作,且是在原集合基础上进行的更新操作
scala.collection.immutable 包下是不变集合
不可变集合也可以模拟修改、添加、删除等操作,但是每次操作不是在原来集合基础上的更新操作,每次都会生产一个新的集合 1、定长List集合 定长list集合的定义:
val list = List(33,55,77,11) list.head //返回第一个元素的值
list.tail //返回除第一个元素外的其他元素的集合
Nil //代表一个空的List集合 总结List集合是由head头和tail尾组成的 向定长list集合添加元素
val list1=88::list //添加元素后生产了一个新的list集合,原list集合元素没有变化
val list2 =99::111::222::list val list3=555::Nil //通过这种方法也能创建一个list集合 删除list集合的元素
list.drop(3) //表示从左数删除3个元素
原list集合元素没有变化 2、变长list集合
定义
val list=scala.collection.mutable.ListBuffer(44,11,88)
添加元素(都是在原集合基础上进行的更新操作)
list += 111
list+=(444,666)
list++= list1
删除元素
-=/--= 变长list集合的转换
list.toList 定长list集合
list.toArray 定长数组 list集合的遍历
for (x<-list){
println(x)
} list集合其他常用方法
list.exists((x:Int)=> {x>55}) //通过exists方法判断list集合里面有没有大于55的元素 简化:
list.exists((x:Int)=> x>55 )
list.exists((x)=> x>55) //scala可以自动推断数据类型
list.exists(x=> x>55 ) //只有一个参数时可以省略括号
list.exists(_ > 55 ) //当匿名函数的参数在函数体中只调用一次时可以这样写 list.filter(_ > 20) //过滤出大于20的元素 3、Set
PPT 参考list array 4、不可变Map集合
定义:
val map=Map("lili"->18,"tom"->19,"mary"->17)
获取value
map("tom")
map("mary")
//map("wangwu") //方法一
if (map.contains("wangwu"))
map("wangwu")
else
-1
//方法二
map.getOrElse("lili",-1) 5、可变map集合 定义
val map1=scala.collection.mutable.Map("lili"->18,"tom"->19,"mary"->17)
更新或添加元素
map1("lili")=19
map1("lio")=21
map1 +=("zhaosi"->23) map集合的遍历 for ((x, y) <- map1) {
println("key is " + x + ",value is " + y)
} for ((key, _) <- map1) {
println("key is " + key)
} for ((_, value) <- map1) {
println("value is " + value)
} for (values <- map1.values){
println("value is " + values)
} 比较安全的遍历方法 for((key,value)<-map1){
println("key is " + key+ ",value is " + map1.getOrElse(key,-1))
} map集合的排序
map1.toList.sorted.toMap