1.基本语法
1).自定义常量(val)----推荐使用
2)变量(var)
3)插值表达式
4)惰性赋值
lazy val 变量名 = 表达式
// 首次使用该值时,才会被加载
println(变量名)
5)标识符
命名规则:支持"撇撇"
变量和方法:小驼峰
类和特征(Trait):大驼峰
包:全部小写
6)数据类型
7)类型转换
a.自动类型转换(小转大)
b.强制类型转换(大转小):
val|var 变量名 = 值.toXxx // 例如强转为 Int 则为 toInt
c.String 类型转换
val|var 变量名 = 数值类型 + ""
val|var 变量名 = 数值类型.toString
d. String 类型转换为数值类型
val|var 变量名 = 数值类型.toXxx // 例如强转为 Int 则为 toInt
8)键盘录入
导包: import scala.io.StdIn
调用方法:通过 StdIn.readXxx() 接收用户键盘录入的数据
9)关系运算符
比较数据值使用 == 或者 !=,比较引用值(对象地址值)使用 eq 方法
10)语句块
Scala 中使用 {} 表示一个语句块,语句块是有返回值的(最后一个逻辑行)。
11)循环
在 Scala 中,没有三元表达式,可以使用 if 表达式替代三元表达式
?a:b
for循环
for (i <- 表达式|数组|集合) {
// 语句块(也叫循环体)
}
break 和 continue(Scala中没有)
需要使用 scala.util.control 包下的 Breaks 类的 breakable 块和 break 方法。
a.实现 break 是用 breakable 将整个 for 表达式包起来
b.实现 continue 是用 breakable 将 for 表达式的循环体包起来
(下划线表示Breaks下的所有包)
12)方法(方法传参默认是 val 类型,即不可变)
定义方法时返回值类型可以省略,由 Scala 编译器自动推断,但是定义递归方法时,不能省略
惰性方法
13)方法参数
a.默认参数:
b.带名参数:(调用时指定)
c.变长参数:(一个方法有且只能有一个变长参数,并且变长参数要放到参数列表的最后边)
14)方法调用
后缀调用法: 对象名.方法名(参数) Math.abs(-1)
中缀调用法: 对象名 方法名 参数 Math max (1, 2)
花括号调用法:Math.abs { Math.abs{-1}
// 语句块
}
无括号调用法:
15)函数 ()=>{}
方法和函数的区别:
方法转换成函数:
val|var 变量名 = 方法名 _
16)Option:表示可选值
在返回一些数据时,难免会遇到空指针异常,可以返回一个 Option 类型的对象来封装具体的数据,从而有效的避免空指针异常。
2.面向对象
1)
主构造器
辅助构造器
2)单例对象:object 单例对象名{}---类似于Java中的静态方法
直接 对象名.方法或者属性来调用
3)伴生对象
一个 class(非静态) 和 一个 object(静态) 具有相同的名字时,这个 object 就被称为伴生对象,这个 class 被称为伴生类。
伴生对象和伴生类必须是相同的名字;
伴生对象和伴生类在同一个 scala 源文件中;
伴生对象和伴生类可以互相访问 private 私有属性。
private[this] ,则表示只能在当前类中访问,即使是伴生对象也无法访问。
apply方法和unapply方法
4)方法重写
父类用 var 修饰的变量,子类不能重写,子类只能重写 val 定义的属性
override
5)类型判断
精确的判断出对象的类型,只能使用 getClass 和 classOf 来实现。
// 精确获取对象的类型
val clazz = p.getClass
val clazz = classOf[类型]
6)抽象
抽象属性:没有初始化值的变量就是抽象属性
抽象方法:没有方法体的方法就是抽象方法
7)trait(特质)--类似于Java中的interface
特质中可以有具体的属性、抽象属性、具体的方法以及抽象方法
只有抽象内容的特质被称为瘦接口,既有抽象内容又有具体内容的特质被称为富接口。
Scala 中不管是类还是特质,都使用继承 extends 关系,特质支持多继承
如果要继承多个特质,则特质之间使用 with 关键字隔开
对象混入trait
val|var 对象名 = new 类 with 特质
构造机制规则
每个特质只有一个无参数的构造器
遇到一个类继承另一个类、以及继承多个 trait 的情况,当创建该类实例时,构造器执行顺序如下:
在 Scala 中,特质也可以继承类,继承后特质会将类中的非私有成员都继承下来。
trait xxx extends xxx
类和特质怎么选择:共性(具体的)内容定义到父类,扩展(模糊的)内容定义到特质。
3.设计模型
1)适配器模型
2)模板方法
钩子函数:让子类来决定模板方法的逻辑执行。比如在炒西红柿鸡蛋的时候,由子类去决定是否要加调料
3)策略模式
4)责任链模式
4.样例类
apply--构造对象
unapply--提取属性
常用于和数据库映射
5.集合
1)分类
不可变(默认):可以安全的并发访问
可变: -----长度和内容都可变(但是Array数组长度不可变,内容可变)
除了Truple(元组),其他都是
2)继承树
3)Traversable
(特质)----类似于Java中的接口
方法
转置:transpose()
拼接:concat()
扫描:scan()等价于scanLeft(), scanRight()--从右往左
获取:
判断:
聚合:
类型转换:toXXX
填充元素:
4) Iterable(迭代器)
遍历集合
分组集合
按索引生成元组
判断集合是否相同
HashSet(1, 5, 2, 3, 4) 和 TreeSet(2, 1, 4, 3, 5) 是否相同?
是,比较的是内容
5)Seq---有序
特质代表按照一定顺序排列的元素序列,序列是一种特别的可迭代集合,它的元素特点是有序(元素存取顺序一致),可重复,有索引。
IndexedSeq 代表索引序列
================================================================
LinearSeq 代表线性序列
Seq的方法
获取元素与长度:size和length都可以
获取元素索引:
判断集合是否包含指定元素
修改元素
6)Set和Map
HashMap:元素特点 Key 唯一、无序。----比较特殊,需要导入mutable包
ListMap:元素特点 Key 唯一、有序(元素添加的顺序)。
TreeMap:元素特点 Key 唯一、排序(按自然顺序排序)。
-------下层实现
7)数组Array
a.不可变数组:数组的长度不允许改变,数组的内容可以改变
使用 数组名(索引) 来获取数组中的元素。----()
数组名.updated(索引, 新值) :修改元素------会产生新的数组,旧的还是原来的值
b.可变数组:数组的长度和内容都是可变的,可以往数组中添加、删除元素。
+= :添加单个元素
-= :删除单个元素
++= :追加多个元素到变长数组中
--= :移除变长数组中的多个元素
数组名(索引) = 新值 或者 数组名.update(索引, 新值) :修改元素-
遍历:
常用方法: sum() :求和。
max() :求最大。
min() :求最小。
sorted() :排序(正序),返回一个新的数组。倒序可以先排序再反转。
reverse() :反转,返回一个新的数组。
8)元组 Tuple
元组的长度和元素都是不可变的
通过元组名.productIterator 的方式来获取该元素的迭代器
9)列表 List
a.不可变列表:列表的元素、长度都是不可变的。
b.可变列表: 列表的元素、长度都是可变的.
列表List的常用方法:
10)集 Set
不可重复,无序,无索引
不可变集:集的元素、长度都是不可变的。(Set)
可变集合:集的元素、长度都是可变的(mutable.Set)
集List常见操作:
遍历
11)映射 Map
由键值对(Key Value)组成的集合。特点是:键具有唯一性,值可以重复
a.不可变 Map:元素、长度都是不可变的(map)
数组名.updated(索引, 新值) --------会产生新的数组,旧的还是没有改变
b.可变 Map:集的元素、长度都是可变的(mutable.Map)
c.遍历 Map
d.常见操作
eg:
12)迭代器 Iterator
13)范围 Range
14)栈 Stack(先进后出)
可变栈:mutable.Stack :通过 List 链表的方式实现,增删快,查询慢。
mutable.ArrayStack :通过 Array 数组的方式实现,查询快,增删慢。
15)队列 Queue(先进先出)
可变:mutable.Queue
6. 函数式编程
1)遍历 foreach
2)简化函数定义
3)去重 distinct
4)映射 map
5)扁平化映射 flatMap
6)过滤 filter
7)排序
8)分组groupBy
9)聚合
fold 和 reduce 很像,只不过多了一个指定初始值的操作。
7.案例
8.模式匹配
a.数组
b.列表
c.元组
要不转换成数组,要不只能case相同数量的
d.集
e.映射
9.结合函数使用
偏函数:PartialFunction[A, B]
map和foreach都是全部元素操作,但是map有返回值,foreach没有返回值
10.IO流
按行读取:source.getLines()
按字符读取:source.buffered
从 URL 或其他源读取
11. 隐式转换 Implicit Conversion
手动导入
自动导入