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的元素 
                
                
        3Set  
            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  
                
原文地址:https://www.cnblogs.com/yin-fei/p/10778759.html