Scala简易教程
Posted 智辉NOTE
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala简易教程相关的知识,希望对你有一定的参考价值。
学习目标:
搭建scala开发环境
学习scala基本语法结构(变量、表达式、if、循环、方法、函数等)
掌握scala集合的使用(数组、元组、List、Set、Map等)
scala简介
scala是运行正在jvm上的多范式编程语言,同时支持面向对象和面向函数编程(函数式编程就是对容器的操作比较多)。
早期,scala刚刚兴起的时候并没有引起太多的重视,随着spark和Kafka这样基于Scala的大数据框架的兴起,scala逐渐进去大数据开发者的眼帘。scala的主要优势在于其表达性
为什么要用scala
开发大数据应用程序(Spark程序,Flink程序);
表达能力强,一行代码抵得上java多行,开发速度快;
兼容java,可以访问庞大的java类库,例如mysql、redis、freemarker,activemq等等(java生态圈非常大)。
scala和java对比
定义三个实体类(用户、订单、商品)
public class User {
private String name;
private List<Order> orders;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
}
object Exercise {
class User(var name: String, var orders: List[Order]); // 用户实体类
class Order(var id: Int, var orders: List[Product]); // 订单实体类
class Product(var id: Int, var category: String); // 商品实体类
}
开发环境安装
java程序编译执行流程
scala执行流程
scala程序运行需要依赖于java类库,必须要有java运行环境,scala才能正确运行;
根据上述流程图,要编译运行scala程序,需要
jdk(jvm)
scala 编译器(scala SDK)
接下来安装:
安装jdk
安装scala sdk
安装IDEA插件;
IDEA 默认不支持scala程序开发,所以需要安装scala插件来支持scala语言;
操作1
下载指定版本IDEA scala插件
IDEA 配置scala插件
重新启动IDEA;
操作2
到IDEA 官网下载版本一致的scala插件;
操作3
选择配置>选择插件
scala解释器
后续我们会使用scala解释器来学习scala基本语法,scala解释器像Linux命令一样,执行一条代码,马上就可以看到执行的结果,用来测试比较方便;
接下来学习:
启动scala解释器;
在scala解释器中执行scala代码;
退出scala解释器
启动scala解释器
要启动scala解释器,只需要一下几步:
安装window键+r
输入scala即可
执行scala代码
在scala的命令提示窗口中输入println("hello world");
退出scala解释器
在scala命令提示窗口中输入:quit,即可退出解释器;
声明变量
在以后的每一天编写的scala程序中都会定义scala变量。那么scala语言如何定义变量呢?
语法格式
java定义变量:
int a = 0;
在scala中,可以通过var或者val定义变量,语法格式如下:
var/val 变量标识:变量类型 = 变量初始值
var num: Int = 10
val score: Double = 16.6
其中
val是定义不可重新赋值的变量;
var定义可以重新赋值的变量;
Note:
scala 中定义变量类型写在变量名后面;
scala语句最后不需要添加分号
在解释器中定义一个变量
!标准语法分号后面有个空格
var变量和val变量
使用类型推荐来定义变量
scala语法要比java语法简洁,可以使用更为简单的方式来定义变量;
惰性赋值
在企业的大数据开发中,有时候会编写非常复杂的SQL语句,这些SQL语句可能有几百行甚至上千行。这些SQL语句如果直接加载到JVM中,会有很大的内存开销,如何解决呢?
当有一些变量保存的数据比较大时,但是不需要直接加载到JVM内存中,可以使用惰性赋值来提高效率;
lazy val/var 变量名 = 表达式
lazy val sql: String ="""select * from adm.itcast_adm_persons
|where day="2012-01-12"
|and hour="01"
|and device_type="ios"
|""".stripMargin
示例:
在程序中需要执行以下比较复杂的SQL语句时,我们希望只用到这个SQL语句才去加载它(和spark的RDD类似)。
可以减少JDK的开销;
字符串
scala 定义多种定义字符串的方式,将来我们可以根据需要选择最方便的定义方式。
使用双引号;
使用插值表达式;
使用三引号
使用双引号
语法
var/val 变量名= "字符串"
实例:
有一个人的名字叫"hadoop",请打印他的名字以及长度;
def main(args: Array[String]): Unit ={
var userName = "hadoop"
println(userName)
println(userName.size)
}
使用插值表达式
scala中,可以使用插值表达式来定义字符串,有效避免大量字符串的拼接;
语法:
var/val 变量名 = s"${变量名/表达式}字符串"
// 插值表达式定义方式
val ret = s"${userName} is senior leader"
// python中是使用f来表示插值表达式
Tip:
在定义字符串之前添加s
在字符串中,可以使用${} 来引用变量或者编写表达式
使用三引号
如果有大段的文本需要保存,就可以使用三引号来定义字符串。例如:保存一大段的SQL语句。三引号中的所有字符串都将作为字符串的值;
语法:
val/var 变量名 = """字符串1
|字符串2""".stripMargin
数据类型与操作符
scala中的类型以及操作符绝大多数和java一样,我们主要来学习
与java不一样的用法
scala类型的继承体系
数据类型
基础类型 | 类型说明 |
---|---|
Byte | 8位带符号整数 |
Short | 16位带符号整数 |
Int | 32位带符号整数 |
Long | 64位带符号整数 |
Char | 16位无符号Unicode字符 |
String | Char类型的序列(字符串) |
Float | 32位双精度浮点数 |
Doubel | 64位双精度浮点数 |
Boolean | true或者false |
注意scala和java类型的区别:
Note:
scala中所有的类型都是用大写字母开头
整数使用Int而不是Integer
scala中定义变量可以不写类型,让scala编译器自动推断
运算符
类别 | |
---|---|
算术运算符 | +, -,*,/ |
关系运算符 | >,< ==,!=,>=,<= |
逻辑运算符 | &&,||,! |
位运算符 | &,|,~, ^,<<,>> |
在scala中没有+=,--运算符
与java不一样,在scala中,可以直接使用==,!=进行比较,他们与equals方式表示一致。而比较两个对象的引用值,使用eq
var str1 = "abc"
var str2 = str1 + ""
println(str1 == str2) // true,等价于str1.equals(str2)
println(str1.eq(str2)) // false, .eq进行引用比较,比较的是地址
equals: 比较值相等;
scala类型的层次结构
所有类型的父类是:Any, 有两个子类AnyVal:所有值类型都是从AnyVal进行继承的;AnyRef是所有引用类型的父类
Unit表示空类型,在java中用void表示;Null是所有引用类型的子类型,可以将Null赋值给任何引用类型;Nothing是所有类型的子类,可以将Nothing赋值给任何类型;
类型 | 说明 |
---|---|
Any | 所有类型的父类,他有两个子类AnyRef和AnyVal |
AnyVal | 所有数值类型的父类 |
AnyRef | 所有对象类型(引用类型)的父类 |
Unit | 表示空,Unit是AnyVal的子类,它只有一个实例(),类似于java中的void,但是scala比java更加面向对象 |
Null | Null是AnyRef的子类,也就是说它是所有引用类型的子类。它的实例是null, 可以将null赋值给任何类型 |
Nothing | 所有类型的子类 不能直接创建该类型的实例,某个方法抛出异常时,返回的就是Nothing类型, 因为Nothing是所有类的子类,那么它可以赋值为任何类型; |
def m3(x: Int, y:Int): Int = {
if(y == 0) {
throw new Exception("这是一个异常")
}
x / y
}
// 当函数抛出异常时,返回值并不是Int而是Nothing
val b: Int = null // 会报错
Null类型并不能转换为Int类型,说明Null类型并不是Int类型的子类。
条件表达式
条件表达式就是if表达式,if表达式可以根据给定的条件判断条件是否满足,根据条件的结构(真或假)决定执行对应的操作。scala的条件表达式和java的条件表达式一样
有返回值的if
scala 的if语句是有返回值,而java语句没有返回值;
在java中有三元表达式,可以将三元表达式赋值给某一个值
与java不一样的是:
Note:
在scala中,条件表达式也是有返回值的;
在scala中,没有三元表达式,可以使用if表达式代替三元表达式;
实例:定义一个变量sex,在定义一个result变量,如果sex 等于male,reult为1,否则result为0;
def if_test(sex: String): Int = {
if (sex == "male") 1 else 0
}
java中的三元表达式:
String name = "sex";
int u = name == "sex"? 0: 1;
System.out.println(u);
块表达式
在scala中,使用{}表示一个块表达式
和if表达式一样,块表达式也是有值的
值就是最后一个表达式的值
val a = {
println("1+1")
1+1
}
println(a) // 就是最后一条语句的值, 块表达式的值还是会被执行
循环
在scala中,可以使用for和while,但是一般推荐使用for表达式,因为for表达式语法更加简洁;
for表达式
语法
for(i <- 表达式/数组/集合){
// 表达式
}
实例:
for(i<- 1 to 10){
print(i)
}
方法二
(1.to 10).toSeq.foreach(println)
(1.to(10)) // 完全面向对象的
中缀调用法
1 to 10 // 等价于1.to(10)
for(i <- 1 to 5){
for (j <- 1 to 5){
print("*")
}
println("")
}
// for(i <- 1 to 3; j <- 1 to 5){print("*"); if (j == 5) println("")}
守卫
for表达式中,可以添加if判断语句,这个if判断就称之为守卫。我们可以使用守卫让for表达式更加简洁。
for(i<- 表达式/数组/集合 if 表达式){
// 表达式
}
打印1 to 10 之间能够被3 整除的数字
for(i <- 1 to 10 if i % 3 == 0){ println(i)}
for 推导式
将来可以使用for推导式生成一个新的集合(一组数据)
在for循环体中,可以使用yield表达式来构建歘一个集合,我们把使用yield的for表达式称之为推导式;
// for 推导式:for表达式中以yield开始,该for表达式会构建出一个集合
var v = for(i <- 1 to 10) yield i * 10
print(v)
// 类似于python的列表推导式
// 输出结果:Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
while循环
scala中的while循环和java中的是一致的;
var i: Int = 0;
while( i < 10){
i = i + 1
print(i)
}
break 和 continue
在scala中,类似java和c++的break/continue关键字被移除掉了
如果一定要使用break/continue,就需要使用scala.util.control 包中的Break类中的breakable和break方法
实现break
用法:
导入Break包, import scala.util.control. Breaks._
使用breakable将for表达式包起来
for表达式中需要退出循环的地方,添加break()方法调用
示例
使用for表达式打印1-100的数字,如果数字达到50,则退出for循环
// 导入scala.util.control.Breaks._
import scala.util.control.Breaks._
breakable{for(i <- 1.to(10)){
if (i > 5){
break()
}
print(i)
}}
实现continue
用法
continue的实现与break类似,但是有一点不同:
Note:
实现break是用breakabel{}将整个for表达式包起来,而实现continue是用breakable{} 将for循环包起来就可以了
打印1 - 100 的数字,使用for表达式来遍历,如果数字能整除10,不打印
for(i <- 1 to 10){
breakable{
if(i % 2 == 0) break()
else print(i)
}
}
以上是关于Scala简易教程的主要内容,如果未能解决你的问题,请参考以下文章