1.输出语句
print("内容")
println("内容")
分号可不写,但是多个语句在一行是必须加分号。
2.常量
在程序运行过程中,其直不能发生改变的量。
2.1分类
1.字面值常量
整型 print(10)
浮点型 print(0.3)
字符型 print('a')
字符串型 print("acd")
布尔常量 print(true)
空常量 print(null)
2.自定义常量
3.变量
在程序执行过程中,其只可以改变的量
3.1语法格式
在scala中可以使用val和var来定义变量,语法格式如下:var/val 变量名:类型=初始值
val:定义不可重新赋值的变量,也就是之定义常量
var:定义可重新赋值的变量
4.字符串
4.1插值表达式
val/var 变量名:类型=s"${变量/表达式}字符串";
注意:在定义字符串以前添加s
在字符串中,可以使用${}来引用变量或者编写表达式
4.2惰性赋值
语法: lazy val/var 变量名 =表达式
5.标识符
变量、方法、类名的命名:大小写英文字符、数字、下划线、$符。
数字不能开头
不能与scala的关键字重合
最好见名知意
命名规范
变量或方法:第二个单词开始首字母大写,其他都小写(小驼峰命名)
类或特质:每个单词首字母都大写(大驼峰命名)
包:全部小写
6.数据类型
Byte 8位带符号整数
Short 16位带符号整数
Int 32位带符号整数
Long 64位带符号整数
Char 16位无符号Unicode字符
String Char类型的序列
Float 32位单精度浮点数
Double 64位双精度浮点数
Boolean true或者false
7.类型转换
值类型转换和引用类型转换。
值类型转换:自动类型转换和强制类型转换
自动类型转换
小范围转大范围 Byte,Short,Char->Int->Long->Float->Double
强制类型转换
大范围转小范围(可能会造成精度缺失问题)
val/var 变量名:数据类型=具体的值.toXXX //XXX表示要转换到的类型
值类型和String类型转换
1.val/var 变量名:数据类型=值类型数据+“”
2.val/var 变量名:数据类型=值类型数据.toString
8.算数运算符
运算符的分类:
算数运算符
赋值运算符
用来进行复制操作的符号
关系运算符
用来进行比较操作的符号
逻辑运算符
进行逻辑操作的符号
位运算符
进制:逢几进一
8421码:用来描述二进制和十进制数据之间的关系,可以快速的计算数据的二进制或十进制形式
原码:十进制转换成二进制数据,该二进制数据即为原码。
正数的原码、补码、反码都一样,不需要特别计算
负数:反码(原码符号位不变,数值位取反),补码=反码+1
位运算符是指按照位(bit)快速操作数值。
分类:
ps:scala中没有三元运算符,使用if-else代替
9.流程控制
顺序结构
程序按照从上至下、从左至右的循序依次逐行执行,中间没有任何判断和跳转。
选择结构(if)
某些代码的执行需要某些特定的判断条件,判断条件成立,则代码执行,否则代码不执行。
循环结构
for循环
格式:for(i< 表达式/数组/集合 ){逻辑代码}
for (i<-1 to 10 ){语句}
循环嵌套
for (i<-1 to 10 ;j<-1 to 10 ){语句}
守卫
for (i<-1 to 10 if i%3==0 ){语句}
while循环
同java,但是scala中没有++和--的语法
do ...while
同java
break和continue
scala中没有break和continue这两个关键字了
如果希望跳出循环(实现break功能),可以使用breakable和break方法
1.导包 import scala.util.control.Breaks._
2.使用breakable将整个循环体包裹起来
3.在循环体中需要退出循环的地方添加break()方法
如果希望跳出本次循环(实现continue功能)
1.导包 import scala.util.control.Breaks._
2.使用breakable将循环体包裹起来
3.在循环体中需要退出循环的地方添加break()方法
10.方法
定义
def 方法名 (参数名:参数类型,参数名:参数类型):[return type]={
//方法体
}
示例:
def getMax(x:Int,y:Int):Int={
if(x>y){
return x
}else{
return y
}
}
惰性方法
当记录方法返回值类型的变量被声明为lazy时,方法的执行将被推迟,直到我们首次使用该值时,方法才会被执行,像这样的方法被称为惰性方法。(lazy不能修饰var类型的变量)
使用场景:打开数据库连接、提升某些特定模块的启动时间、确保对象中的某些字段能优先初始化。
示例:
方法的调用方式
1.后缀调用法
对象名.方法名(参数) Math.abs(-1)
2.中缀调用法
对象名 方法名 参数 Math abs -1
3.花括号调用法
对象名.方法名{表达式1} Math.abs{-10} //只有一个参数时才可以使用
4.无括号调用法
如果方法没有参数,可以省略方法后面的括号
def sayhello() =println("你好")
//掉用该方法
sayhello;
函数
语法: val 函数变量名=(参数名:参数类型,参数名:参数类型,。。。)=》函数载体
注意:函数是一个对象
函数也有参数列表和返回值
函数定义不需要使用def
无需指定返回值类型
val sum=(x:Int,y:Int)=>{
return x+y;
}
方法和函数区别
在Java中,方法和函数是一个东西,只是叫法不同
在scala中
方法是类属于类或者对象的,在运行时是加载到jvm的方法区中
函数可以赋值给一个变量,在运行时,是加载到jvm的堆内存中
11.类和对象
什么是面向对象:
面向对象是一种编程思想,他是基于面向过程的,强调的是以对象为基础完成各种操作
面向对象的三大思想:
1.更符合人们的思考习惯
2.把复杂的事情简单化
3.把程序员从执行者变成指挥者
什么是类:
类是属性和行为的集合,是一个抽象的概念。
属性(成员变量):用来描述事物的外在特征的
行为(成员方法):表示事物能够做什么
什么是对象:
对象是类的集体体现和实现
面向对象的三大特征:
封装 继承 多态
下划线初始化成员变量(必须带类型,否则不知道赋什么初始化值)
val类型的成员变量,必须自己手动初始化
访问权限修饰符
和Java一样,可以通过访问修饰符控制成员变量和方法是否可以被外界访问
在scala中,没有public关键字,只要没有被private和protected修饰的成员都是公共的
类的构造器
主构造器
语法:class 类名(var/val 参数名:类型=默认值,var/val 参数名:类型=默认值){//构造代码块}
辅助构造器
除了主构造器之外,都是辅助构造器(辅助构造器的名字都是this,且不能修改)
单例对象
scala中是没有static关键字的,要想定义类似于java中的static变量、方法,就要使用单例对象
定义单例对象
格式: obect 单例对象名{ }
在单例对象中定义方法
main方法
在scala中运行一个程序必须有一个主方法,在Java中main方法是静态的,但是在Scala中没有静态方法,所以main方法必须放在一个单例对象中。
继承APP特质
创建一个object,继承APP特质(trait),然后将需要编写在main方法的代码,下载object的钩爪方法体内。
//普通
object test1 {
def main(args:Array[String]): Unit ={
println("你好")
}
}
//继承
object test1 extends App {
println("你好")
}
伴生对象
package com.zyz.spark_core.wc
object test1 {
//定义伴生类 G1
class G1 {
//定义toWar()方法 表示打仗
def toWar() = println(s"打仗,使用${G1.armsName}武器")
}
//定义伴生对象
object G1 { //里边内容都是静态的
//定义私有成员变量表示武器
private val armsName = "机关炮";
}
//定义main方法作为程序主入口
def main(args: Array[String]): Unit = {
//创建伴生类的对象
val c = new G1();
//调用towar方法
c.toWar();
}
}
apply方法
12.继承
语法
使用extends关键字来实现继承
可以在子类中定义父类中没有的字段和方法,或者重写父类的方法
类和单例对象都可以有父类
class/object A类 extends B类{//子承父业
}
isInstanceof和asInstanceof
isInstanceof:判断对象是否为指定类的对象
asInstanceof:将对象转换为自定类型
var trueOrFalse:Boolean=对象.isInstanceof[类型]
val 变量=对象.asInstanceof[类型]
getClass和classOf
p.getClass可以精确获取对象的类型
classOf[类名]可以精确获取数据类型
使用==可以直接比较类型
抽象类
通过abstract关键字来实现(不能通过new创建对象)
定义:如果类中有抽象字段或者抽象方法,那么该类就应该是一个抽象类
抽象字段:没有初始化值的变量就是抽象字段
抽象方法:没有方法体的方法就是一个抽象方法
//定义抽象类
abstract class 抽象类名{
//定义抽象字段
val/var 抽象字段名:类型;
//定义抽象方法
def 方法名(参数:参数类型,参数:参数类型):返回类型
}
类继承单个特质
特点:
1.提高代码的复用性
2.提高代码的可扩展性和可维护性
3.类与特质之间是继承关系,只不过类与类之间只支持单继承,但类与特质之间既可以单继承,也可以多继承。
4.scala中的特质可以有普通字段、抽象字段、普通方法、抽象方法
语法
trait 特质名称{
//普通字段
//抽象字段
//普通方法
//抽象方法
}
继承特质
class 类名 extends 特质1 with 特质2{
//重写抽象字段
//重写抽象方法
}
单例对象继承特质
需求:
创建一个logger特质,添加log(msg:String)方法
创建一个warning特质,添加warn(msg:String)方法
创建一个单例对象consolelogger,继承上述特质,重写抽象方法
编写main方法,调用对象中的方法
object classdemo{
trait logger{
def log(msg:String)
}
trait warning{
def warn(msg:String)
}
//创建一个单例对象consolelogger
object consolelogger extends logger with warning{
override def log(msg:String):Unit=println(s"控制台日志信息:${msg}")
override def warn(msg:String):Unit=println(s"控制台警告信息:${msg}")
}
}
成员变量也一样继承(抽象的需要重写)
对象混入trait
语法: var 对象名=new 类 with 特质
trait实现适配器模式
适配器模式
模板方法模式
class A{//父类 封装的是公共部分
def 方法名(参数列表)={//具体方法
//第一步
//第二步 调用抽象方法
//第三步
}
//抽象方法
}
class B extends A{
//重写抽象方法
}
trait的构造机制
object classDemo1 {
//创建 logger特质 在构造器中打印“执行logger构造器”
trait Logger {
println("执行Logger构造器 2")
}
//创建 MyLogger特质继承自Logger特质 在构造器中打印“执行MyLogger构造器”
trait MyLogger extends Logger {
println("执行MyLogger构造器 3")
}
//创建 TimeLogger特质继承自Logger特质 在构造器中打印“执行TimeLogger构造器”
//
trait TimeLogger extends Logger{
println("执行TimeLogger构造器 4")
}
//创建person类,在构造器中打印 “person构造器”
class Person{
println("Person构造器 1")
}
class student extends Person with MyLogger with TimeLogger {
println("student构造器 5" )
}
def main(arg:Array[String])={
var s= new student;
}
输出
13.包
简介
格式
作用域
包对象
包的可见性
包的引入
14.数组
数组就是存储多个同类型的元素,每个元素都有编号,且编号都是从0 开始数的
定长数组
数组的长度不允许改变,数组内容是可变的
语法:
val/var 变量名=new Array[元素类型](元素长度)
or
val/var 变量名=Array(元素1,元素2,.....)
注意:
例子
def main(args: Array[String]) = {
var arr = new Array[Int](10);
arr(0) = 11;
println(arr(0))
var arr1=Array("java","scala","python")
println(arr1.length)
}
结果
变长数组
数组的长度和内容都是可变的,可以往数组中添加、删除元素
语法:
1.先导入类
import scala.collection.mutable.ArrayBuffer
2.创建数组
val/var 变量名=ArrayBuffer[元素类型]()
or
val/var 变量名=ArrayBuffer(元素1,元素2,....)
例子:
import scala.collection.mutable.ArrayBuffer
object arrayDemo {
def main(args: Array[String]) = {
var arr = ArrayBuffer[Int]();
var arr1 = ArrayBuffer("hadoop", "storm", "spark")
println(s"arr:${arr}")
println(s"arr1:${arr1}")
}
}
结果:
增删改元素
遍历数组
数组的常用算法
15.元组
元组一般存储多个不同类型的值(元组的长度和元素都是不可变的)
格式
val/var 元组=(元素1,元素2,.....)
或者
val/var 元组=元素1->元素2 (ps:只适用于元组中只有两个元素的情况)
示例:
val 元组=("张三",23)
val 元组="张三"->23
访问元组的元素
元组._编号
通过 元组名.productIterator 的方式,来获取该元组的迭代器 val it=tp.productIterator;for(i<-it) print(i)
16.列表
不可变列表
列表元素和长度都是不可变的
语法:
可变列表
列表元素和长度都是可变的
语法:
可变列表的常用操作:
列表的常用操作:
17.集(set)
Set:代表没有重复元素的集合,特点:唯一、无序
不可变集(默认使用)
指:元素和集的长度都不可变
语法:
常见操作:
获取集的大小 size
遍历集 与遍历数组一样
添加一个元素 + (返回一个新的Set)
拼接两个集或集和离别哦 ++(返回一个新的Set)
删除一个元素 - (返回一个新的Set)
批量删除 --(返回一个新的Set)
可变集
可变集:元素和长度都可变
导包:
import scala.collection.mutable.Set
声明方式与不可变集一致
18.映射(Map)
映射指的是Map,它是由键值对(key,value)组成的集合,键具有唯一性
不可变Map
指元素和长度都不可变
语法:
可变Map
map的基本操作
19.迭代器(iterator)
scala针对每一类集合都提供了迭代器(iterator),用迭代来访问集合
注意事项:
20.函数式编程
21.模式匹配
简单模式匹配
包含一系列的备选项,每个备选项都开始于关键字case。
格式
变量 match {
case "常量1“ => 表达式1
case "常量2“ => 表达式2
case "常量3“ => 表达式3
case _ => 表达式4
}
匹配类型
例子
var a:Any ="hadoop"
var result= a match {
case x:String =>s"${x}是一个String类型的数据"
case x:Int =>s"${x}是一个Int 类型的数据"
case x:Double =>s"${x}是一个Double 类型的数据"
case _ =>"未匹配"
}
守卫
守卫是指可以在case语句中添加if条件判断
格式:
变量 match {
case 变量名 if 条件1 => 表达式1
case 变量名 if 条件2 => 表达式2
case 变量名 if 条件3 => 表达式3
...
case _ => 表达式4
}
匹配样例类
格式
示例:
匹配集合
同上方一样
例子:
匹配列表
同上
匹配元组
同上
变量声明中的模式匹配
匹配for表达式
option类型
option类型的对象封装具体的对象,可以有效的避免空指针异常。
格式:
例子:
正则表达式
格式:
var 正则对象名=" " " 正则表达式 " " ".r
例子:
22.异常处理
捕获异常
格式:
try{
//可能会出现问题的代码
}
catch{
case ex : 异常类型1 =>//代码
case ex : 异常类型2 =>//代码
}
finally{
//代码
}
抛出异常
该方式处理完异常,程序会终止执行
23.提取器
一个类如果要支持模式匹配,必须要实现一个提取器。
提取器就是指 unapply 方法。
样例类自动实现了 unapply 方法。
要实现提取器,只需要在该类的伴生对象中实现一个unapply 方法即可。
格式:
24.读取数据
在scala中Source单例对象提供了一些便捷方法,可以从自定的数据源中获取数据,获取数据前需要先导入包:import scala.io.Source
按行读取
按行读取(getLines()方法),返回迭代器类型的对象,可以通过toArray、toList方法将数据放入数组或者列表。
格式:
按字符读取
scala还提供 以字符为单位读取数据 这种方式类似于迭代器,读取以后可以通过hasNext()、next()方法灵活获取数据。
格式:
读取词法单元和数字
格式:
读取二进制文件
示例:
向文件中写入数据
同java一样
序列化于反序列化
反序列化
隐式转换
隐式转换:指的是用implicit关键字声明的带有单个参数的方法。该方法时自动被调用的
隐式参数:用implicit关键字修饰的变量
implicit关键字是在scala的2.10版本中出现的
推荐一个笔记:https://blog.csdn.net/qq_41112238/article/details/106462165