·scala入门:基本语法(变量和数据类型、运算符、流程控制)
·核心特性:函数式编程、面向对象、集合
·其他特色:模式匹配、异常处理、隐式转换、泛型
Spark—新一代内存级大数据计算框架,是大数据的重要内容。
Spark就是使用Scala编写的。因此为了更好的学习Spark, 需要掌握Scala这门语言。
Spark的兴起,带动Scala语言的发展
Scala是一门以Java虚拟机(JVM)为运行环境并将面向对象和函数式编程的最佳特性结合在一起的 静态类型编程语言(静态语言需要提前编译的如:Java、c、c++等,动态语言如:js)。
1)Scala是一门多范式的编程语言,Scala支持面向对象和函数式编程。(多范式,就是多种编程方 法的意思。有面向过程、面向对象、泛型、函数式四种程序设计方法。)
2)Scala源代码(.scala)会被编译成Java字节码(.class),然后运行于JVM之上,并可以调用现有 的Java类库,实现两种语言的无缝对接。
3)Scala单作为一门语言来看,非常的简洁高效。
4)Scala在设计时,马丁·奥德斯基是参考了Java的设计思想,可以说Scala是源于Java,同时马丁·奥 德斯基也加入了自己的思想,将函数式编程语言的特点融合到JAVA中, 因此,对于学习过Java的同学, 只要在学习Scala的过程中,搞清楚Scala和Java相同点和不同点,就可以快速的掌握Scala这门语言。
1)jdk已经安装
2)scala安装包
在本机编辑高级环境中添加scala环境
测试环境是否正确搭建
win+R,输入cmd进入终端,输入scala并按回车
在File->在下拉菜单中点击 Setting... ->点击 Plugins->
下载完成之后重启idea
创建一个新的项目,引入scala框架
创建scala文件
编写hello scala实例,object类型
package cn.itjdb.chapter01
object hello {
def main(args: Array[String]): Unit = {
println("hello scala")
}
}
运行后,可以在控制台打印输出“hello scala”
·注:object和class区别
参数声明方式:java->类型 参数名
scala->参数名:类型
public修饰符:scala中没有public关健字,如果不声明访问权限,那么就是公共的。
static修饰符:scala中没有静态语法,所以没有static关键字。
void关键字:表示返回值,但是不遵循面向对象语法,所以scala中没有,但是有Unit类型,表示没有返回值
scala中:方法名(参数列表):返回值类型
scala中声明方法必须采用关键字def声明
scala中方法实现肤值给方法声明,所以中间需要等号连接
Scala是一个完全面向对象的语言,所以没有静态语法,为了能调用静态语法(模仿静态语法)采用伴生对象单例的方式调用方法
官方编程指南: https://www.scala-lang.org/
单行注释://
多行注释:/**/
文档注释:/**
*
*/
可以使用ctrl + alt + L 来进行代码格式化
常量:在程序执行的过程中,其值不会被改变的变量
基本语法:var 变量名 [: 变量类型] = 初始值 var i:Int = 10
val 常量名 [: 常量类型] = 初始值 val j:Int = 20
注意:能用常量的地方不用变量
在声明/定义一个变量时,可以使用 var 或者 val 来修饰,var 修饰的变量可改变, val 修饰的变量不可改。
object TestVar {
def main(args: Array[String]): Unit = {
//(1)声明变量时,类型可以省略,编译器自动推导,即类型推导
var age = 18
age = 30
//(2)类型确定后,就不能修改,说明 Scala 是强数据类型语言。
// age = "tom" // 错误
//(3)变量声明时,必须要有初始值
// var name //错误
//(4)在声明/定义一个变量时,可以使用 var 或者 val 来修饰,var 修饰
的变量可改变,val 修饰的变量不可改。
var num1 = 10 // 可变
val num2 = 20 // 不可变
num1 = 30 // 正确
//num2 = 100 //错误,因为 num2 是 val 修饰的
}
}
Scala 对各种变量、方法、函数等命名时使用的字符序列称为标识符。即:凡是自己可 以起名字的地方都叫标识符。
命名规则:
(1)以字母或者下划线开头,后接字母、数字、下划线
(2)以操作符开头,且只包含操作符(+ - * / # !等)
(3)用反引号`....`包括的任意字符串,即使是 Scala 关键字(39 个)也可以 (不推荐)• package, import, class, object, trait, extends, with, type, for • private, protected, abstract, sealed, final, implicit, lazy, override • try, catch, finally, throw • if, else, match, case, do, while, for, return, yield • def, val, var • this, super • new • true, false, null
var `if` : String = ""
1)基本语法
(1)字符串,通过+号连接
(2)printf 用法:字符串,通过%传值。
(3)字符串模板(插值字符串):通过$获取变量值
package cn.itjdb.chapter02
/**
* 字符串输出
* 1)基本语法
* (1)字符串,通过+号连接
* (2)printf 用法:字符串,通过%传值。
* (3)字符串模板(插值字符串):通过$获取变量值
*
*/
object StringPrint {
def main(args: Array[String]): Unit = {
val name:String="tom"
val age:Int=19
println(name+" "+age)
printf("name=%s,age=%d\n",name,age)
println(s"${name}已经${age}岁了")
val s2="sadasd" +
"sdasd" +
"asdas" +
"as"
println(s2)
//三双引号包围多行字符串,可以保持字符串的格式
val s1=
s"""
|select
| name,
| age
|from user
|where name="$name" and age=${age+2}
|""".stripMargin
println(s1)
}
}
基本语法 StdIn.readLine()、StdIn.readShort()、StdIn.readDouble()
// 1 输入姓名
println("input name:")
var name = StdIn.readLine()
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,是所有数据类型的子类,主要用在一个函数没有明确返回值时使 用,因为这样我们可以把抛出的返回值,返回给任何的变量或者函数。
注:Null 可以赋值给任 意引用类型(AnyRef),但是不能赋值给值类型(AnyVal)
当 Scala 程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数值类型,这 个就是自动类型转换(隐式转换)。数据类型按精度(容量)大小排序为:
基本说明:
(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成 精度大的那种数据类型,然后再进行计算。
(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动 类型转换。
(3)(byte,short)和 char 之间不会相互自动转换。
(4)byte,short,char 他们三者可以计算,在计算时首先转换为 int 类型。
自动类型转换的逆过程,将精度大的数值类型转换为精度小的数值类型。使用时要加上 强制转函数,但可能造成精度降低或溢出,格外要注意。
强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
//强制转换,将数据由高精度转换为低精度,就需要使用到强制转换
var num = 2.5.toInt
println(num)
//数值类型和 String 类型间转换
//基本类型转 String 类型(语法:将基本类型的值+"" 即可)
var str1:String=8+""
println(str1)
// String 类型转基本数值类型
var n7=str1.toByte
println(n7)
var n8:Int = "12".toInt
println(n8)
var n9:Int=130
var b1:Byte=n9.toByte
println(b1)
Scala 运算符的使用和 Java 运算符的使用基本相同,只有个别细节上不同。
注:对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整 数部分而舍弃小数部分。
Java 和 Scala 中关于==的区别:
Java: ==比较两个变量本身的值,即两个对象在内存中的首地址; equals 比较字符串中所包含的内容是否相同
Scala:==更加类似于 Java 中的 equals,eq则是比较两个对象在内存中的首地址
用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个 Boolean 值。
赋值运算符就是将某个运算后的值,赋给指定的变量。
注:Scala 中其实是没有运算符的,所有运算符都是方法。 1)当调用对象的方法时,点.可以省略 2)如果函数参数只有一个,或者没有参数,()可以省略
让程序有选择的的执行,分支控制有三种:单分支、双分支、多分支
单分支:
if (条件表达式) { 执行代码块 }
双分支:
if (条件表达式) { 执行代码块 1 } else { 执行代码块 2 }
三分支:
if (条件表达式 1) { 执行代码块 1 } else if (条件表达式 2) { 执行代码块 2} …… else { 执行代码块 n }
注:Scala 中 if else 表达式其实是有返回值的,具体返回值取决于满足条件的 代码体的最后一行内容。
在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层。 分支外面的分支结构称为外层分支。嵌套分支不要超过 3 层。
if(){ if(){ }else{} }
在 Scala 中没有 Switch,而是使用模式匹配来处理。
Scala 也为 for 循环这一常见的控制结构提供了非常多的特性,这些 for 循环的特性被称 为 for 推导式(for的模式匹配)或 for 表达式。
for(i <- 1 to 3){ print(i + " ") } println()
(1)i 表示循环的变量,<- 规定 to
(2)i 将会从 1-3 循环,前后闭合
for(i <- 1 until 3) { print(i + " ") } println()
(1)这种方式和前面的区别在于 i 是从 1 到 3-1
(2)即使前闭合后开的范围
for(i <- 1 to 3 if i != 2) { print(i + " ") } println()
(1)循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为 true 则进入循环 体内部,为 false 则跳过,类似于 continue。
for (i <- 1 to 10 by 2) { println("i=" + i) }
说明:by 表示步长
for(i <- 1 to 3; j <- 1 to 3) { println(" i =" + i + " j = " + j) }
说明:没有关键字,所以范围后一定要加;来隔断逻辑
(1)for 推导式一行中有多个表达式时,所以要加 ; 来隔断逻辑
(2)for 推导式有一个不成文的约定:当 for 推导式仅包含单一表达式时使用圆括号, 当包含多个表达式时,一般每行一个表达式,并用花括号代替圆括号,
val res = for(i <- 1 to 10) yield i println(res)
说明:将遍历过程中处理的结果返回到一个新 Vector 集合中,使用 yield 关键字。
·倒序打印
如果想倒序打印一组数据,可以用 reverse。
for(i <- 1 to 10 reverse){ println(i) }
语法:循环变量初始化 while (循环条件) { 循环体(语句) 循环变量迭代 }
说明:
(1)循环条件是返回一个布尔值的表达式
(2)while 循环是先判断再执行语句
(3)与 for 语句不同,while 语句没有返回值,即整个 while 语句的结果是 Unit 类型()
(4)因为 while 中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免 的使用变量,而变量需要声明在 while 循环的外部,那么就等同于循环的内部对外部的变量 造成了影响,所以不推荐使用,而是推荐使用 for 循环。
do...while循环控制
语法:循环变量初始化; do{循环体(语句) 循环变量迭代 } while(循环条件)
说明:
(1)循环条件是返回一个布尔值的表达式
(2)do..while 循环是先执行,再判断
说明:
Scala 内置控制结构特地去掉了 break 和 continue,是为了更好的适应函数式编程,推 荐使用函数式的风格解决break和continue的功能,而不是一个关键字。Scala中使用breakable 控制结构来实现 break 和 continue 功能。
采用 Scala 自带的函数,退出循环
import scala.util.control.Breaks
def main(args: Array[String]): Unit = {
Breaks.breakable(
for (elem <- 1 to 10) {
println(elem)
if (elem == 5) Breaks.break()
}
)
println("正常结束循环")
}
说明:
(1)将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for,while,do…while 均可以作为外层循环和内层循环。【建议一般使用两层,最多不要超过 3 层】
(2)设外层循环次数为 m 次,内层为 n 次,则内层循环体实际上需要执行 m*n 次。
实例:打印九九乘法表
object TestWhile {
def main(args: Array[String]): Unit = {
for (i <- 1 to 9) {
for (j <- 1 to i) {
print(j + "*" + i + "=" + (i * j) + "\t")
}
println()
}
}
}