大数据学习笔记(scala)

1、Scala六大特性

java和scala可以无缝混编(都是基于JVM)
类型推测(不必指定类型,自动推测类型)
支持并发和分布式(Actor)
特质:trait(集结了java中抽象类和接口的产物)
模式匹配(match case :类似于java中的switch case)
高阶函数(参数时函数或者返回值是参数)

2、Scala的安装使用

本教程介绍在Windows下安装Scala2.10版本。安装包可以去官网下载。Scala官网。
下载完成之后,解压在电脑合适位置(记住该位置)。然后配置环境变量(和java配置环境变量一样)
新建一个系统变量SCALA_HOME,值是Scala安装包的位置。

编辑Path环境变量,添加;%SCALA_HOME%\bin;%SCALA_HOME%\jre\bin

此时scala安装完毕,使用win+r输入cmd打开命令行,然后输入scala -version可以看到安装的scala的版本号。测试成功。

3、Scala基础

 1)、数据类型
     Byte 		8bite的有符号数字,范围在-128 – 127
     Short 		16bite的有符号数字,范围值在-32868 – 32767
     Int 			32bite的有符号数字,范围在-21亿 – 21亿
     Long 		64bite的有符号数字,范围在 负的2的16次方 – 2的16次方
     Float 		32bite 单精度浮点数
     Double 	64bite 双精度浮点数
     Char 		16bite Unicode字符
     String 		字符串
     Boolean 布尔类型
     Unit 		表示无值,和其他语言的void相同
     Null 		空值或者空引用
     Nothing 所有其他类型的子类型,表示没有值
     Any 		所有类型的超类,任何实例都属于Any类型。类似于java的Object
     AnyRef	所有引用类型的超类
     AnyVal	所有值类型的超类
     Nil			长度为0的List

在这里插入图片描述

2)、变量和常量的声明
    定义变量或者常量的时候,可以写上返回类型,也可以不写,如下:
    变量:var age:Int = 20或者var age2 = 18
    常量:val age:Int = 20或者val age2 = 18(常量不可以再次赋值)
3)、类和对象

创建类:

class Person{
       val name = "zhangsan"
       val age = 18
       def sayName() = {
           "my name is "+ name
       }
   }

创建对象:

 object Lesson_Class {
     def main(args: Array[String]): Unit = {
        val person = new Person()
        println(person.age);
        println(person.sayName())
     }
  }

4)、if else

用法与java基本相同

val age =18 
    if (age < 18 ){
    	println("no allow")
    }else if (18<=age&&age<=20){
    	println("allow with other")
    }else{
    	println("allow self")
    }

5)、for,while,do…while

讲解Scala的循环之前,先讲解Scala的一个特性:until和to(主要区别是:until前闭后开,to前闭后闭)

   println(1 until 10 )       //不包含最后一个数,打印 1,2,3,4,5,6,7,8,9
   println(1 until (10 ,3 ))  //步长为3,从1开始打印,打印1,4,7
   println(1 to 10 )          //打印 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
   println(1 to (10 ,2))      //步长为2,从1开始打印 ,1,3,5,7,9

在逻辑上,Scala中的循环跟java中的循环一样,只是使用的方式有些区别,下面分别做介绍。
for循环(九九乘法表)

    for(i <- 1 until 10 ;j <- 1 until 10){
      if(i>=j){
    	  print(i +" * " + j + " = "+ i*j+"	") 
      }
      if(i==j ){
          println()
      }
    }

与java中不一样的是,for里面可以加判断,如下(判断要用分号分割,可以使用判断来跳出循环,Scala中没有break和countiue,需要使用的话,需要调用javaApi):

   for(i<- 1 to 10 ;if (i%2) == 0 ;if (i == 4) ){
       println(i)
   }

while与dowhile跟java中判断逻辑一样,下面贴个简单的while例子:

var index = 0 
    while(index < 100 ){
    	println("第"+index+"次while 循环")
        index += 1 
    }

注意点:scala中不能使用count++,count—只能使用count = count+1 ,count += 1
for循环用yield 关键字返回一个集合val list = for(i <- 1 to 10 ; if(i > 5 )) yield i
for循环中可以加条件判断,分号隔开

4、Scala函数

1)、普通函数

函数格式:

def 函数名(变量名:变量类型,...):返回值类型 = {
	   函数体
   }

下面是Scala函数的一些规则和注意点:

    函数定义语法 用def来定义
    可以定义传入的参数,要指定传入参数的类型
    方法可以写返回值的类型也可以不写,会自动推断,有时候不能省略,必须写,比如在递归函数中或者函数的返回值是函数类型的时候。
    scala中函数有返回值时,可以写return,也可以不写return,会把函数中最后一行当做结果返回。当写return时,必须要写函数的返回值。
    如果返回值可以一行搞定,可以将{}省略不写。(def fun1 (a : Int , b : Int)= a+b)
    传递给方法的参数可以在方法中使用,并且scala规定方法的传过来的参数为val的,不是var的。
    如果去掉方法体前面的等号,那么这个方法返回类型必定是Unit的。这种说法无论方法体里面什么逻辑都成立,scala可以把任意类型转换为Unit.假设,里面的逻辑最后返回了一个string,那么这个返回值会被转换成Unit,并且值会被丢弃。

2)、递归函数

递归函数(求阶乘)

def fun2(num :Int) :Int= {
      if(num ==1)
        num
      else 
        num * fun2(num-1)
   }

3)、包含参数默认值的函数

默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值。
如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称。

def fun3(a :Int = 10,b:Int) = {
        println(a+b)
   }
   fun3(b=2)

4)、可变参数个数的函数

多个参数用逗号分开。

def fun4(elements :Int*)={
       var sum = 0;
       for(elem <- elements){
          sum += elem
       }
       sum
   }
   println(fun4(1,2,3,4))

5)、匿名函数

匿名函数分为有参匿名函数、无参匿名函数、有返回值的匿名函数。(可以将匿名参数的返回给一个val声明的值,匿名函数不能显式的声明返回值)

//有参数匿名函数
    val value1 = (a : Int) => {
      println(a)
    }
    value1(1)
    
    //无参数匿名函数
    val value2 = ()=>{
      println("我爱Angelababy")
    }
    value2()
    
    //有返回值的匿名函数
    val value3 = (a:Int,b:Int) =>{
      a+b
    }
    println(value3(4,4)) 

6)、嵌套函数

def fun5(num:Int)={
       def fun6(a:Int,b:Int):Int={
          if(a == 1){
             b
          }else{
             fun6(a-1,a*b)
          }
       }
       fun6(num,1)
    }
    println(fun5(5))

7)、偏应用函数

偏应用函数是一种表达式,不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。

def log(date :Date, s :String)= {
       println("date is "+ date +",log is "+ s)
    }
    
    val date = new Date()
    //想要调用log,以上变化的是第二个参数,可以用偏应用函数处理
    val logWithDate = log(date,_:String)
    logWithDate("log11")
    logWithDate("log22")
    logWithDate("log33")

8)、高阶函数

函数的参数是函数,或者函数的返回类型是函数,或者函数的参数和函数的返回类型都是函数的函数。

 //函数的参数是函数
    def hightFun(f : (Int,Int) =>Int, a:Int ) : Int = {
       f(a,100)
    }
    def f(v1 :Int,v2: Int):Int  = {
       v1+v2
    }
    
    println(hightFun(f, 1))
    
    //函数的返回是函数
    //1,2,3,4相加
    def hightFun2(a : Int,b:Int) : (Int,Int)=>Int = {
       def f2 (v1: Int,v2:Int) :Int = {
          v1+v2+a+b
       }
       f2
    }
    println(hightFun2(1,2)(3,4))
    
    //函数的参数是函数,函数的返回是函数
    def hightFun3(f : (Int ,Int) => Int) : (Int,Int) => Int = {
       f
    } 
    println(hightFun3(f)(100,200))
    println(hightFun3((a,b) =>{a+b})(200,200))
    //以上这句话还可以写成这样
    //如果函数的参数在方法体中只使用了一次 那么可以写成_表示
    println(hightFun3(_+_)(200,200))

9)、柯里化函数

可以理解为高阶函数的简化

 def fun7(a :Int,b:Int)(c:Int,d:Int) = {
       a+b+c+d
    }
    println(fun7(1,2)(3,4))

5、Scala集合

1)、数组

创建数组:

//创建类型为Int 长度为3的数组
    val arr1 = new Array[Int](3)
    //创建String 类型的数组,直接赋值
    val arr2 = Array[String]("s100","s200","s300")
    //赋值
    arr1(0) = 100
    arr1(1) = 200
    arr1(2) = 300

遍历数组:

 for(i <- arr1){
        println(i)
    }
    arr1.foreach(i => {
        println(i)
    })

创建二维数组:

val secArray = new Array[Array[String]](5)
for(index <- 0 until secArray.length) secArray(index) = new Array[String](3)

2)、list

list是不可变的,对list进行添加删除或者取值等操作均会返回一个新的list。

   val list = List(1,3,5,9)
   println(list.contains(9))
   val dropList = list.drop(2)
   dropList.foreach { println }
   val reList = list.reverse
   reList.foreach { x => print(x + "\t") }

3)、set

set是一个非重复的集合,若有重复数据,则会自动去重。

   val set = Set(1,3,5,8,1,6,5,8)
   set.foreach { x => print(x + "\t") }

4)、map

map是K-V键值对集合。

//创建map
   val map = Map(
       "1" -> "bj" ,
       2 -> "sh",
       3 -> "gz"
    )
    
    //map遍历
    for(x <- map){
       println("====key:"+x._1+",value:"+x._2)
    }
    
    //遍历key
    var keys = map.keys
    //获取key的迭代器
    var keyIterator = keys.iterator
    while(keyIterator.hasNext){
       val key = keyIterator.next()
       println(key + "\t" + map.get(key).get)
    }

5)、元组

与列表一样,与列表不同的是元组可以包含不同类型的元素。元组的值是通过将单个的值包含在圆括号中构成的。创建过程可加new关键词,也可不加。

//创建二元组,下面两句话效果相同
    val t2 = new Tuple2(1,"hello")
    val tt2 = (1,"hello")
    
    //创建三元组,下面两句话效果相同
    val t3 = Tuple3(2,"bj","come")
    val tt3 = (2,"bj","come")
    
    //创建tt3的迭代器
    val tupleIte = tt3.productIterator
    while(tupleIte.hasNext) print(tupleIte.next + "\t")
    
    //反转,只针对二元组
    val swap = tt2.swap
    
    //toString
    println(tt3.toString())

6、Scala trait特性

Scala Trait(特征)相当于java中抽象类和接口的集合体,不只是具备接口的特征,还可以定义属性和方法的实现。一般情况下Scala的类可以继承多个Trait,从结果来看就是实现了多重继承。Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait。
继承的多个trait中如果有同名的方法和属性,必须要在类中使用“override”重新定义。并且trait中不可以传参数。

//定义一个trait
trait Read {
  val readType = "Read"
  val gender = "m"
  def read(name:String){
	println(name+" is reading")
  }
}
//继承上面的trait
class Person() extends Read{
  override val gender = "f"
}


7、Scala 模式匹配

模式匹配类似于java的switch case。Scala的模式匹配不仅可以匹配值还可以匹配类型、从上到下顺序匹配,如果匹配到则不再往下匹配、都匹配不上时,会匹配到case _ ,相当于default、match 的最外面的”{ }”可以去掉看成一个语句。

def match_test(m:Any) = {
       m match {
         case 1 => println("nihao")
         case m:Int => println("Int")
         case _ => println("default")
       }
    }

8、Scala 样例类

使用了case关键字的类定义就是样例类(case classes),样例类是种特殊的类。实现了类构造参数的getter方法(构造参数默认被声明为val),当构造参数是声明为var类型的,它将帮你实现setter和getter方法。
样例类默认帮你实现了toString,equals,copy和hashCode等方法。
样例类可以new, 也可以不用new。

case class Person1(name:String,age:Int)

object Lesson_CaseClass {
   def main(args: Array[String]): Unit = {
      val p = new Person1("zhangsan",10)
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值