Scala基础知识

通过本篇文章来记录学习的笔记,有遗忘的地方很快能够记起。

1.Scala中的常量(常量指的是: 在程序的运行过程中, 其值不能发生改变的量.)

  • 整型常量

  • 浮点型常量

  • 字符常量

  • 字符串常量

  • 布尔常量

  • 空常量

代码示例:

//整型常量
println(10)
//浮点型常量
println(10.3)
//字符常量, 值要用单引号括起来
println('a')
//字符串常量, 值要用双引号括起来
println("abc")
//布尔常量, 值只有true和false
println(true)
//空常量
println(null)

2.Scala中的变量(变量, 指的就是在程序的执行过程中, 其值可以发生改变的量. )

语法格式:

val/var 变量名:变量类型 = 初始值
  • val定义的是不可重新赋值的变量, 也就是自定义常量.

  • var定义的是可重新赋值的变量

代码示例:

    //根据格式来写
    var a: Int = 10
    val b: String = "hello"
    //简写
    var c = 10
    val d = "hello"

3.字符串

字符串的定义方式:

  • 使用双引号

  • 使用插值表达式

  • 使用三引号

使用双引号 :

格式:

val/var 变量名 = “字符串”

代码示例:

    val str = "hello world"
    var str1 = "hello world"

使用插值表达式:

使用场景:避免大量字符串的拼接

格式:

val/var 变量名 = s"${变量/表达式}字符串"

代码示例:

    var a = 10
    var b = 20
    println(s"${a}")
    println(s"${b}")
    println(s"${a + b}")
    println(s"a + b = ${a + b}")

使用三引号:

使用场景:如果有大段的文本需要保存,就可以使用三引号来定义字符串。例如:保存一大段的SQL语句。三个引号中间的所有内容都将作为字符串的值。

格式:

val/var 变量名 = """字符串1
字符串2"""

代码示例:

    var sql = """select
                |	*
                |from
                |    t_user
                |where
                |    name = "zhangsan"""".stripMargin
    println(sql)

4.惰性赋值

使用场景:

在企业的大数据开发中,有时候会编写非常复杂的SQL语句,这些SQL语句可能有几百行甚至上千行。这些SQL语句,如果直接加载到JVM中,会有很大的内存开销, 如何解决这个问题呢?

当有一些变量保存的数据较大时,而这些数据又不需要马上加载到JVM内存中。就可以使用惰性赋值来提高效率。

格式:

lazy val 变量名 = 表达式

代码示例:

    lazy val sql =
      """insert overwrite table adm.itcast_adm_personas
        select
        a.user_id,
        a.user_name,
        a.user_sex,
        a.user_birthday,
        a.user_age,
        a.constellation,
        a.province,
        a.city,
        a.city_level,
        a.hex_mail,
        a.op_mail,
        a.hex_phone,
        a.fore_phone,
        a.figure_model,
        a.stature_model,
        b.first_order_time,
        b.last_order_time,
          ...
        d.month1_hour025_cnt,
        d.month1_hour627_cnt,
        d.month1_hour829_cnt,
        d.month1_hour10212_cnt,
        d.month1_hour13214_cnt,
        d.month1_hour15217_cnt,
        d.month1_hour18219_cnt,
        d.month1_hour20221_cnt,
        d.month1_hour22223_cnt
        from gdm.itcast_gdm_user_basic a
          left join gdm.itcast_gdm_user_consume_order b on a.user_id=b.user_id
        left join gdm.itcast_gdm_user_buy_category c on a.user_id=c.user_id
        left join gdm.itcast_gdm_user_visit d on a.user_id=d.user_id;""".stripMargin

5.标识符

标识符就是用来给变量, 方法, 类等起名字的.

命名规则:

  • 必须由大小写英文字母, 数字, 下划线_, 美元符$, 这四部分任意组合组成.

  • 数字不能开头.

  • 不能和Scala中的关键字重名.

  • 最好做到见名知意.

命名规范:

  • 变量或方法: 从第二个单词开始, 每个单词的首字母都大写, 其他字母全部小写(小驼峰命名法).
  • 类或特质(Trait): 每个单词的首字母都大写, 其他所有字母全部小写(大驼峰命名法)
  • 包: 全部小写, 一般是公司的域名反写, 多级包之间用.隔开.

6.数据类型

scala类型层次结构:

7.类型转换

值类型的类型转换分为:

  • 自动类型转换

  • 强制类型转换

自动类型转换:

  • 自动类型转换从小到大分别为:Byte, Short, Char -> Int -> Long -> Float -> Double

代码示例:

    var a = 3
    var b = 3.3
    var c = a + b
    println(a.getClass.getSimpleName)
    println(b.getClass.getSimpleName)
    println(c.getClass.getSimpleName) //c自动转换为double类型

强制类型转换:

范围大的数据类型值通过一定的格式(强制转换函数)可以将其转换成范围小的数据类型值, 这个动作就叫: 强制类型转换.

注意: 使用强制类型转换的时候可能会造成精度缺失问题!

格式:

val/var 变量名:数据类型 = 具体的值.toXxx		//Xxx表示你要转换到的数据类型

代码示例:

    var a = 10.5
    var b = a.toInt
    println(a)
    println(b)
    println(a.getClass.getSimpleName)
    println(b.getClass.getSimpleName)

值类型和String类型之间的相互转换:

1.值类型的数据转换成String类型:

格式一:

val/var 变量名:String = 值类型数据 + ""

格式二:

val/var 变量名:String = 值类型数据.toString

代码示例:

    var a = 10
    var b = 2.3
    var c = true
    //方式一
    var a1 = a + ""
    var b1 = b + ""
    var c1 = c + ""
    println(a1.getClass.getSimpleName)
    println(b1.getClass.getSimpleName)
    println(c1.getClass.getSimpleName)
    //方式二
    var a2 = a.toString
    var b2 = b.toString
    var c2 = c.toString
    println(a2.getClass.getSimpleName)
    println(b2.getClass.getSimpleName)
    println(c2.getClass.getSimpleName)

2.String类型的数据转换成其对应的值类型

格式:

val/var 变量名:值类型 = 字符串值.toXxx	//Xxx表示你要转换到的数据类型
  • String类型的数据转成Char类型的数据, 方式有点特殊, 并不是调用toChar, 而是toCharArray

代码示例:

    var a = "100"
    var b = "100.100"
    var c = "false"
    var d = "hello world"

    var a1 = a.toInt
    var b1 = b.toDouble
    var c1 = c.toBoolean
    var d1 = d.toCharArray

    println(a1.getClass.getSimpleName)
    println(b1.getClass.getSimpleName)
    println(c1.getClass.getSimpleName)
    println(d1.getClass.getSimpleName)

键盘录入

代码示例:

    var str = StdIn.readLine("请输入一个字符串:")
    println(str)

    println("请输入一个整数:")
    var num = StdIn.readInt()
    println(num)

运算符

  • 算术运算符:+ - * / % (Scala中没有++,--)

  • 赋值运算符: = += -= .......

  • 关系运算符: > < >= <= == !=

  • 逻辑运算符:&& || !

  • 位运算符

Scala流程控制

  • 顺序结构 :程序是按照从上至下, 从左至右的顺序, 依次逐行执行的, 中间没有任何判断和跳转.

  • 选择(分支)结构:if... if...else... if... else if... else

  • 循环结构:for while do.while

重点说一下循环结构:

在Scala中, for的格式和用法和Java中有些差异, Scala中的for表达式功能更加强大.

格式:

for(i <- 表达式/数组/集合) {
    //逻辑代码
}

代码示例:

打印10次"Hello, Scala!"

    var nums = 1 to 10
    for (i <- nums) {
      println("Hello,Scala")
    }

上述代码可以简写成:

for (i <- 1 to 10) println("Hello,Scala " + i)

守卫

for表达式中,可以添加if判断语句,这个if判断就称之为守卫,过滤出一些满足条件的结果。。我们可以使用守卫让for表达式更简洁。

格式:

for(i <- 表达式/数组/集合 if 表达式) {
    //逻辑代码
}

代码示例:

使用for表达式打印1-10之间能够整除3的数字         

for (i <- 1 to 10 if i % 3 == 0) println(i)

for推导式

for结构可以在每次执行的时候创造一个值,然后将包含了所有产生值的集合作为for循环表达式的结果返回,集合的类型由生成器中的集合类型确定。注意:for 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。Scala 中 for 循环是有返回值的。如果被循环的是 Map,返回的就是 Map,被循环的是 List,返回的就是 List,以此类推。

格式:

for (变量 <- 表达式) yield {语句块}

 代码示例:

生成一个10、20、30...100的集合

    var data = for (i <- 1 to 10) yield i * 10
    println(data)
    println(data.getClass.getSimpleName)

While循环

scala中while循环和Java中是一致的, 所以学起来非常简单.

语法:

初始化条件
while(判断条件) {
    //循环体
    //控制条件
}

代码示例:

    var num = 0
    while (num <= 10) {
      println(num)
      num = num + 1
    }

 

break和continue

  • 在scala中,类似Java和C++的break/continue关键字被移除了

  • 如果一定要使用break/continue,就需要使用scala.util.control包下的Breaks类的breablebreak方法。

使用breakable代码示例:

    breakable {
      for (i <- 1 to 10) {
        if (i == 5) {
          break()
        }
        println(i)
      }
    }

 实现continue代码示例:

    for (i <- 1 to 10) {
      breakable {
        if (i % 3 == 0) {
          break()
        }
        println(i)
      }
    }

 

实现一个九九乘法表:

    for (i <- 1 to 9) {
      for (j <- 1 to i) {
        print(s"${j} * ${i} = ${j * i}\t")
      }
      println()
    }

Scala函数和方法

1.方法

格式:

def 方法名(参数名:参数类型, 参数名:参数类型) : [return type] = {
    //方法体
}
  • 参数列表的参数类型不能省略

  • 返回值类型可以省略,由scala编译器自动推断

  • 返回值可以不写return,默认就是{}块表达式的值

代码示例:

  1. 定义一个方法getMax,用来获取两个整型数字的最大值, 并返回结果(最大值).

  2. 调用该方法获取最大值, 并将结果打印到控制台上.

    //方法一:标准写法
    def getMax(a: Int, b: Int): Int = {
      return if (a > b) a else b
    }

    val max = getMax(45, 20)
    println(max)

    //方法二:优化版
    def getMax1(a: Int, b: Int) = if (a > b) a else b

    val max1 = getMax1(12, 23)
    println(max1)

scala定义方法可以省略返回值的数据类型,由scala自动推断返回值类型。这样方法定义后更加简洁。

代码示例:定义递归方法, 求5的阶乘.

    //方法一:标准写法
    def factor(n: Int): Int = {
      if (n == 1) {
        return 1
      }
      return n * factor(n - 1)
    }

    var num = factor(5)
    println(num)

    //方法二:优化版
    def factor1(n: Int): Int = if (n == 1) 1 else n * factor1(n - 1)

    var num1 = factor1(5)
    println(num1)

函数

scala支持函数式编程,将来编写Spark/Flink程序会大量使用到函数, 目前, 我们先对函数做一个简单入门, 在后续的学习过程中, 我们会逐步重点讲解函数的用法.

语法:

val 函数变量名 = (参数名:参数类型, 参数名:参数类型....) => 函数体
  • 在Scala中, 函数是一个对象(变量)

  • 类似于方法,函数也有参数列表和返回值

  • 函数定义不需要使用def定义

  • 无需指定返回值类型

代码示例:

  1. 定义一个计算两个整数和的函数

  2. 调用该函数

    val getSum = (a: Int, b: Int) => a + b
    var result = getSum(1, 2)
    println(result)

 

方法和函数的区别

在Java中, 方法和函数之间没有任何区别, 只是叫法不同. 但是在Scala中, 函数和方法就有区别了, 具体如下:

  • 方法是隶属于类或者对象的,在运行时,它是加载到JVM的方法区中

  • 可以将函数对象赋值给一个变量,在运行时,它是加载到JVM的堆内存中

  • 函数是一个对象,继承自FunctionN,函数对象有apply,curried,toString,tupled这些方法。方法则没有

结论: 在Scala中, 函数是对象, 而方法是属于对象的, 所以可以理解为: 方法归属于函数.

代码示例:

//1. 定义方法
def add(x:Int,y:Int)= x + y

//2. 尝试将方法赋值给变量.
//val a = add(1, 2)		//不要这样写, 这样写是在"调用方法", 而不是把方法赋值给变量
val a = add

//3. 上述代码会报错
<console>:12: error: missing argument list for method add
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `add _` or `add(_,_)` instead of `add`.
       val a = add

 

方法转换为函数

有时候需要将方法转换为函数. 例如: 作为变量传递,就需要将方法转换为函数

格式:

val 变量名 = 方法名 _		//格式为: 方法名 + 空格 + 下划线

代码示例:

  1. 定义一个方法用来计算两个整数和

  2. 将该方法转换为一个函数,并赋值给变量

    def add(a: Int, b: Int): Int = {
      return a + b
    }

    var sum = add _
    var result = sum(1, 2)
    println(result)

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿瞒有我良计15

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值