一、Scala介绍
1、Scala语言特点
学习Scala是因为Spark框架就是有Scala编写的,想学习Spark,首先需要对Scala有一定的了解。
Scala的语言特点:
Scala是一门以Java虚拟机(JVM)为运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言(静态语言需要提前编译的如:Java、c、c++等,动态语言如:js)。
(1)Scala是一门多范式的编程语言,Scala支持面向对象和函数式编程。(多范式,就是多种编程方法的意思。有面向过程、面向对象、泛型、函数式四种程序设计方法。)
(2)Scala源代码(.scala)会被编译成Java字节码(.class),然后运行于JVM之上,并可以调用现有的Java类库,实现两种语言的无缝对接。
(3)Scala单作为一门语言来看,非常的简洁高效。
2、Scala和Java的关系
可以说Scala就是在Java的基础上,加上了自己函数式编程思想的语言。Scala的SDK中有Java的类库,有Scala自己特有的类库,也对Java的部分类库做了特定的包装。Scala同样的经过SDK编译后,会生成.class文件,然后可以在各种环境(windows,linux,unix)的JVM上面运行。也能说Scala就是兼容Java的,所以Scala同时需要Java的JDK和自己的SDK的支持。
3、Scala的环境搭建
(1)首先需要按照对应版本的Java的JDK,并配置好环境变量
(2)下载对应的Scala安装文件,并解压到不带中文的目录下
(3)对应的配置Scala的环境变量,SCALA_HOME,开启cmd,输入scala测试即可
(4)IDEA默认不支持Scala的开发,需要安装插件;下载插件(scala-intellij-bin-2017.2.6.zip)并按照File->Setting->Plugins->Install plugin from disk的步骤找到并安装插件
(5)Maven默认也不支持Scala的开发,需要引入Scala框架,在项目上右击,按照Add Framework Support->选择 Scala->点击 OK步骤引入Scala框架
4、简单的Scala程序介绍
object Hello {
def main(args: Array[String]): Unit = {
println("HelloScala")
System.out.println("hello scala from java")
}
}
object:关键字,声明一个单例对象(或者伴生对象)跟同名的类形成伴生关系;
Scala中无Static关键字,由Object实现类似静态方法的功能。
class:关键字,声音一个伴生类,伴生类和伴生对象的私有属性是可以共有的。
def:关键字,声明方法,形式如:
def 方法名(参数名:参数类型):返回值类型 = { 方法体 }
Unit:空返回值类型,Java中空返回类型用Void,Scala中空返回有Unit。
[String] 表示泛型,字符串类型,Scala用中括号表示泛型,Java中用尖括号<>表示泛型。
Scala 中不用添加分号作为每行的结束,当然添加了也是不会报错,建议按照规范不必要添加。
scala 中可以直接调用Java中的类库,当然使用类库需要先导包,system.out.println() 这种常用的系统默认预先导入包了。
5、Scala的编译命令
Java的编译命令:
javac HelloScala.java
Java的运行命令:
java HelloScala
Scala的编译命令:
scalac HelloScala.scala
Scala的运行命令:
scala HelloScala
二、变量和数据类型
1、注释
Scala 注释使用和 Java 完全一样。
(1)单行注释://
(2)多行注释:/* */
(3)文档注释:
/***
*
*/
2、变量和常用(重点)
scala中有变量和常量之分,变量的值可以被修改,常量的值不能被修改;变量使用var 定义,常量使用val 定义。
java中变量和常量的定义如下,java中使用final关键字,来定义常量:
int a = 10
final int b = 20
scala中变量和常量的定义格式如下:
var 变量名[:变量类型] = 初始值
val 常量名[:常量类型] = 初始值
var i:Int = 10
val j:Int = 20
关于var 和val 定义的一些规则如下:
(1)声明变量时,类型可以省略,编译器会自动推导,即类型推导
var a = 10 //系统自动推导为Int类型
var name = "alice" //系统自动推导为String类型
(2)类型确定后,就不能修改,说明 Scala 是强数据类型语言
var a:Int = 123 //Int类型不能修改为String类型,或者String的值不能赋给Int类型的变量
a = "123" // error
(3)变量声明时,必须要有初始值
var a1: Int // error 必须要有初始值,这两种方式都是错误的
var a2 // error
(4)在声明/定义一个变量时,可以使用 var 或者 val 来修饰,var 修饰的变量可变,val 修饰的变量不可改。
var a: Int = 15
val b: Int = 25
a = 18
b = 20 // error,val 修饰的值不能改变
(5)var 修饰对象时,对象和属性均可变;val 修饰对象时,对象不可变,对象里面的属性可变
// var 修饰的常规变量可以修改,修饰的引用变量也是可以修改的,如下:
var alice = new Student(name="alice",age=20)
alice = new Student(name="Alice",age=18)
alice = NULL
// val 修饰的引用变量不能修改,但是类里面的属性可以修改,同时必须在创建类时在属性上面有定义,如:
Student(name:String,var age:Int)
val bob = new Student(name="Bob",age=13)
// bob = new Student(name="bob",age=20) // error,对象不能重新赋值,不能修改
bob.age = 14 // 类里面的属性可以修改,下面打印将会打印出年龄为14
bob.printInfo()
3、标识符命名
Scala的命名跟java的命名规则一样,以字母或者下划线开头,后接字母、数字、下划线。有以下两个特例:
(1)以操作符开头,且只包含操作符(+ - * / # !)等为合法命名,如下命名为合法:
var -+/#:String = "hello"
(2)用反引号
包括的任意字符串,即使是 Scala 关键字(39 个)也属合法
var `for` = 123
var `def` = "123"
4、数据类型(重点)
Java数据类型
Java基本类型:
char、byte、short、int、long、float、double、boolean
Java引用类型:(对象类型)
由于Java有基本类型,而且基本类型不是真正意义的对象,即使后面产生了基本类型的包装类,但是仍然存在基本数据类型,所以Java语言并不是真正意思的面向对象。
Java基本类型的包装类:
Character、Byte、Short、Integer、Long、Float、Double、Boolean
注意:Java中基本类型和引用类型没有共同的祖先类。但是scala是有的。
Scala数据类型
1、Scala数据类型
Scala的所有类型的祖先类是Any,下面分2大类,分别是AnyVal类(数值类型)和AnyRef类(引用类型),并且不管是数值类型还是引用类型都是对象。
- AnyVal类(数值类型):
- Unit: 空值类,相当于Java当中的void,常用于返回值为空的情况
- StringOps: 是对Java当中的String的增强类型
- Char: 字符类型
- Boolean: 布尔类型
- Double -> Float -> Long -> Int -> Short -> Byte: 数值类型,精度逐渐递减
- AnyRef类(引用类型)
- Scala collections
- Other Scala classes
- all java classes
- Null: 只有一个对象就是null,它是所有引用类型的子类
Nothing: 是所有数据类型的子类,主要用在一个函数没有明确返回值时使用,因为这样我们可以把抛出的返回值,返回给任何的变量或者函数。
需要注意的是:
(1)Scala中所有类型,包括数据都是对象,且都是Any的子类
(2)Scala数据类型仍然遵守自动转换,低精度的值类型向高精度值类型转换时会自动转换(隐式转换)
(3)Null 是所有引用类型的子类
(4)Nothing 是所有数据类型的子类
2、整数类型
整数类型(Byte[1]、Short[2]、Int[4]、Long[8]),Scala默认的整数类型为Int型,声明其他类型需要加上类型定义,且长整型需要在后面加L或者l;
val a3 = 10 // int型
val a4:Long = 32333333333L // 长整型定义
val a5:Byte = (10+20) // byte型
3、浮点类型
浮点类型(Float,Double),scala中默认是Double类型,声明Float类型,需要在后面添加f或F。
val a6 = 3.6 //Double型
val a7:Float = 3.8f //Float型
4、字符类型
用单引号‘’扣起来的表示字符。
5、布尔类型
(1)布尔类型也叫Boolean 类型,Booolean 类型数据只允许取值 true 和 false
(2)boolean 类型占 1 个字节
6、Unit类型,Null类型和Nothing类型
Unit:表示无值,和Java语言中 void 等同。用作不返回任何结果的方法的结果的返回值类型。Unit 只有一个实例值,写成(),可以查看里面的toString()方法。
Null:null , Null 类型只有一个实例值 null,null可以赋值给任意的引用类型AnyRef,不能赋值给数值类型AnyAvl
Nothing:Nothing 类型在 Scala 的类层级最低端;它是任何其他类型(AnyRef、AnyAvl)的子类型。当一个函数,我们确定没有正常的返回值时(也就是发生异常情况时),可以用 Nothing 来指定返回类型,这样有一个好处,就是我们可以把返回的值(异常)赋给其它所有的函数或者变量(兼容性)
5、类型转换
自动类型转换
当 Scala 程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数值类型,这个就是自动类型转换(隐式转换)。按照顺序可以有以下顺序:
Byte => Short => Int => Long => Float => Double
一般自动转换的规则如下:
(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算。
(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。
(3)byte,short和 char 之间不会相互自动转换,char在自动转换时,会自动转换成int类型
(4)byte,short,char 他们三者可以计算,在计算时首先会转换为 int 类型,然后再计算
强制类型转换
精度高的想转成精度低的就需要用到强制转换,但要注意会造成精度降低或者溢出问题,且强转只针对于最近的操作数有效,常常会使用括号提升优先级。
val a1:Int = 10*3.5.toInt // 结果为30,先将3.5转为Int型的3
val a2:Int = (10*3.5).toInt // 结果为35,将整体结果35.0转为35
var b1:Byte = 1
// 此处编译报错,因为b1+1时,系统默认会将b1转化成int类型,再相加;
// 但加完需要再赋给b1的时候,变成了int类型赋给Byte类型,因为是精度大的类型赋给精度小的类型,所以报错
// 此处需要加括号强转 b1 = (b1+1).toByte
b1 = b1+1
// 此处不会报错,因为直接将b1转成了Int类型
b1 += 1
数值类型和String类型转换
(1)基本类型转 String 类型(语法:将基本类型的值+“” 即可)
var num: Int = 123
var strNum1 = num.toString // 或者
var strNum2 = num+""
(2)String 类型转基本数值类型(语法:s1.toInt、s1.toFloat、s1.toDouble、s1.toByte、s1.toLong、s1.toShort)但要注意非数值的字符串转成数值会报错。
var str1 = "123"
val str2 = "a123"
val num1 = str1.toInt
val num2 = str2.toInt //报错
6、输出和输入
输出:
(1)字符串连接,通过+号连接,* 重复
val name: String = alice
val age: Int = 20
println(age + "年龄" + name + "姓名")
println(name * 3) // 多次打印字符串
(2)printf 用法:字符串,通过%占位符传值,并跟上对应的类型
println("%d年龄 %s姓名",age,name)
(3)双引号前面加上s""为字符串模板(插值字符串),通过 获取变量值,后面的 {}获取变量值,后面的 获取变量值,后面的{}即可对应相应的值
println(s"${
age}年龄 ${
name}