scala_1
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