本文目录
一、Scala入门
1. 概述
Spark—新一代内存级大数据计算框架,是大数据的重要内容。Spark就是使用Scala编写的。因此为了更好的学习Spark, 而需要掌握Scala这门语言。
2.Scala和Java的关系
Scala是基于Java的,它可以直接引用Java的各种类库。在语法上,Scala比Java更加简洁。
3.Scala语言特点
Scala是一门以Java虚拟机(JVM)为运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言(静态语言需要提前编译的如:Java、c、c++等,动态语言如:js)。
1)Scala是一门多范式的编程语言,Scala支持面向对象和函数式编程。(多范式,就是多种编程方法的意思。有面向过程、面向对象、泛型函数式四种程序设计方法。)
2)Scala源代码(.scala)会被编译成Java字节码(.class),然后运行于JVM之上,并可以调用现有的Java类库,实现两种语言的无缝对接。
4.Scala环境搭建
4.1 安装步骤
(1)确保JDK1.8安装成功
(2)下载对应的Scala安装文件scala-2.12.11.zip
(3)解压scala-2.12.11.zip至D:\Tools
(4)配置Scala的环境变量
二、变量和数据类型
1.注释
(1)单行注释://
(2)多行注释:/* /
(3)文档注释:/**
*
*/
2.变量和常量(重点)
常量:在程序执行的过程中,其值不会被改变的变量
注:在Scala中,能用常量的地方不用变量
var 变量名[: 变量类型] = 初始值
val 常量名[: 常量类型] = 初始值
package chapter02
import chapter01.Student
object Test02_Variable {
def main(args: Array[String]): Unit = {
//声明一个变量通用语法
var a: Int = 10
// 1.声明变量时,类型可以省略,编译器自动推导,即类型推导
var a1 = 10
val b1 = 23
// 2.类型确定后,就不能修改,说明Scala是强数据类型语法
var a2 = 15 //a2类型为Int
// 错误:a2 = 'hello': String
// 3.变量声明时,必须要有初始值
// var a3: Int // error
// 4.在声明/定义一个变量时,可以使用var或者val来修饰,var修饰的变量可改变,val修饰的变量不可改
a1 = 12
// b1 = 20 // error
// 引用类型中类型为var表示alice对象可改
var alice = new Student(name="alice", age=20)
alice = new Student(name = "Alice", age = 20)
alice = null
val bob = new Student(name = "bob",age=20)
bob.age = 21
bob.printerInfo()
}
}
3.标识符的命名规范
命名规则:
(1)以字母或者下划线开头,后接字母、数字、下划线
(2)以操作符开头,且只包含操作符(+ - * / # !等)
(3)用反引号`…`包括的任意字符串,即使是 Scala 关键字(39 个)也可以
package chapter02
object Test03_Identifier {
def main(args: Array[String]): Unit = {
}
// 1.以字母或者下划线开头,后接字母、数字、下划线
val hello: String = ""
var Hello123 = ""
val _abc = 123
// 2.以操作符开头,且只包含操作符(+-*/#!等)
val -+/% = ""
// 3.用反引号“....”包括的任意字符串、即使是Scala关键字也可以
val "if" = "if"
println("if")
}
4.字符串
(1)字符串,通过+号连接
(2)printf 用法:字符串,通过%传值。
(3)字符串模板(插值字符串):通过$获取变量值
package chapter02
object Test04_String {
def main(args: Array[String]): Unit = {
// 1.字符串通过+号连接
val name: String = "alice"
val age: Int = 20
println(age + "岁的" + name + "在学校学习")
// *号用于将一个字符串复制多次拼接
println(name * 3)
// 2.printf用法:字符串,通过%传值,同C语言
printf("%d岁的%s在学校学习",age,name)
println()
// 3.字符串模板(插值字符串):通过$获取变量值
println(s"${age}岁的${name}在学校学习")
val num: Double = 2.3456
println(f"The num is ${num}%2.2f") //格式化模板字符串
println(raw"The num is ${num}%2.2f")
// 三引号表示字符串,保持多行字符串的原格式输出
val sql = s"""
|select *
|from
| student
|where
| name = ${name}
|and
| age > ${age}
|""".stripMargin
println(sql)
}
}
5.键盘输入
所用方法:StdIn.readLine()、StdIn.readShort()、StdIn.readDouble()
package chapter02
import scala.io.StdIn
object Test05_StdIn {
def main(args: Array[String]): Unit = {
println("请输入您的名字")
val name: String = StdIn.readLine()
println("请输入您的年龄:")
val age: Int = StdIn.readInt()
// 控制台打印输出
println(s"欢迎${age}岁的${name}来到学校学习")
}
}
6.数据类型(重点)
1)Scala中一切数据都是对象,都是Any的子类。
2)Scala中数据类型分为两大类:数值类型(AnyVal)、引用类型(AnyRef),不管是值类型还是引用类型都是对象。
3)Scala数据类型仍然遵守,低精度的值类型向高精度值类型,自动转换(隐式转换)
4)Scala中的StringOps是对Java中的String增强
5)Unit:对应Java中的void,用于方法返回值的位置,表示方法没有返回值。Unit是 一个数据类型,只有一个对象就是()。Void不是数据类型,只是一个关键字
6)Null是一个类型,只 有一个对 象就 是null。它是所有引用类型(AnyRef)的子类。
7)Nothing,是所有数据类型的子类,主要用在一个函数没有明确返回值时使用,因为这样我们可以把抛出的返回值,返回给任何的变量或者函数。
7.整数类型(Byte、Short、Int、Long)
数据类型 | 描述 |
---|---|
Byte [1] | 8 位有符号补码整数。数值区间为 -128 到 127 |
Short [2] | 16 位有符号补码整数。数值区间为 -32768 到 32767 |
Int [4] | 32 位有符号补码整数。数值区间为 -2147483648 到 2147483647 |
Long [8] | 64 位有符号补码整数。数值区间为 -9223372036854775808 到9223372036854775807 = 2 的(64-1)次方-1 |
这里我们需要注意的是各数据类型的数值区间。
8.浮点类型(Float、Double)
数据类型 | 描述 |
---|---|
Float [4] | 32 位, IEEE 754 标准的单精度浮点数 |
Double [8] | 64 位 IEEE 754 标准的双精度浮点数 |
9.字符类型(Char)
字符类型可以表示单个字符,字符类型是 Char。用 ’ ’ 表示
10.布尔类型:Boolean
(1)布尔类型也叫 Boolean 类型,Booolean 类型数据只允许取值 true 和 false
(2)boolean 类型占 1 个字节。
11.Unit 类型、Null 类型和 Nothing 类型(重点)
数据类型 | 描述 |
---|---|
Unit | 表示无值,和其他语言中 void 等同。用作不返回任何结果的方法的结果类型。Unit 只有一个实例值,写成()。 |
Null | null , Null 类型只有一个实例值 null |
Nothing | Nothing 类型在 Scala 的类层级最低端;它是任何其他类型的子类型。 |
当一个函数,我们确定没有正常的返回值,可以用 Nothing 来指定返回类
型,这样有一个好处,就是我们可以把返回的值(异常)赋给其它的函数
或者变量(兼容性)|
package chapter02
import chapter01.Student
object Test07_DataType {
def main(args: Array[String]): Unit = {
// 1.整数类型
val a1: Byte = 127
val a2: Byte = -128
// val a2: Byte = 128 //error
val a3 = 12 // 整数默认类型为Int
val a4 = 133333333333L //长整型数值定义
val b1: Byte = 10
// 正确
val b2: Byte = 10 + 20
// 错误
// val b3: Byte = b1+20
val b3: Byte = (b1+20).toByte
// 2.浮点类型
val f1 = 1.1234 // Double类型
val f2 = 1.1234f // Float类型
// 3.字符类型
val c1: Char = 'a'
val c2: Char = '9'
val c3: Char = '\t' // 制表符
val c4: Char = '\n' // 换行符
// 4.布尔类型
val isTrue: Boolean = true
// 5.空类型
// 5.1 空值Unit
def m1(): Unit = {
println("m1被调用执行")
}
val a = m1()
println(a)
// 5.2 空引用Null,只能赋给引用类型
var student: Student = new Student("alice",20)
student = null
// 5.3 Nothing
def n1(n:Int): Int = { //需返回一个公共父类。因为Nothing是所有类的子类,所以也是Int的子类
if(n == 0)
throw new NullPointerException
else
return n
}
val b = n1(0)
println(b)
}
}
12.类型转换
12.1 自动转换
(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算。
(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。
(3)(byte,short)和 char 之间不会相互自动转换。
(4)byte,short,char 他们三者可以计算,在计算时首先转换为 int 类型。
12.2 强制类型转换
(1)将数据由高精度转换为低精度,就需要使用到强制转换
(2)强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
12.3 数值类型和 String 类型间转换
(1)基本类型转 String 类型(语法:将基本类型的值+"" 即可)
(2)String 类型转基本数值类型(语法:s1.toInt、s1.toFloat、s1.toDouble、s1.toByte
注:在将 String 类型转成基本数值类型时,要确保 String 类型能够转成有效的数据,比如我们可以把"123",转成一个整数,但是不能把"apple"转成一个整数。否则就会出现异常。
package chapter02
object Test08_DataTypeConversion {
def main(args: Array[String]): Unit = {
// 1 自动类型转换
// 1.自动提升原则,以高精度为准
val a1: Byte = 10
val b1: Long = 2342L
val result1: Long = (a1+b1) //result的类型不能为Int,因为Long的精度比Int的高
val result11: Int = (a1+b1).toInt //强制转换
// 2.把精度大的数值类型赋值给精度小的数值类型时,就会报错。反之则进行自动转换
val a2: Byte = 10
val b2: Int = a2
// val c2: Byte = b2 //error
// 3.(byte,short)和char之间不会互相自动转换
val a3: Byte = 10
val b3: Char = 'b'
// val c3: Byte = b3 // 报错
// 4.byte,short,char三者可以计算,在计算时首先转换为int类型
val a4: Byte = 12
val b4: Short = 25
val c4: Char = 'c'
val result4: Int = a4+b4
val result44: Int = a4+b4+c4
// 2 强制类型转换
// 强制转换有可能造成数据精度降低或者数据溢出
// 1.将数据由高精度转换为低精度,就需要使用强制转换
val n1: Int = 2.5.toInt // 直接取整数部分
// 2.强制符号只针对最近的操作数有效,往往会使用小括号提升优先级
val n2: Int = (2.6+3.7).toInt
// 3 数值类型和字符串类型转换
// (1) 数值转String
val n: Int = 27
val s: String = n+""
// (2) String转数值
val m: Int = "12".toInt
val f: Float = "12.3".toFloat
// val f2: Int = "12.3".toInt //error
val f2: Int = "12.3".toDouble.toInt
}
}
三、运算符
Scala 运算符的使用和 Java 运算符的使用基本相同,只有个别细节上不同
package chapter03
object Test01_Operator {
def main(args: Array[String]): Unit = {
// 1.算术运算符
val result1 = 10 / 3 // 3
// println(result1)
val result2: Double = 10 / 3 // 3.0
val result3: Double = 10.0 / 3.0 //3.33333
println(result3.formatted("%.2f"))
val result5: Int = 10 % 3
// 2.比较运算符
val s1: String = "hello"
val s2: String = new String("hello")
println(s1 == s2) //true
println(s1.equals(s2)) //true
println(s1.eq(s2)) // False,判断两对象地址是否相同
// 3.逻辑运算符,短路执行特点
def m(n :Int): Int = {
println("m被调用")
return n
}
val n = 1
println((4>5) && m(n) > 0)
// 判断一个字符串是否为空
def isNotEmpty(str: String): Boolean = {
return str != null && ! ("".equals(str.trim))
}
isNotEmpty(null)
// 4.运算符本质
val n1: Int = 12
val n2: Int = 37
println(n1 + n2)
println(n1.+(n2))
}
}