第1章、Scala入门
- object标识的是单例对象;
- object中所有的属性和方法都是类似java static修饰的。scala中没有static关键字;
- class中所有的属性和方法都是类似java非static修饰的。所以scala main方法必须定义在object中;
- scala没有public关键字,默认就是类似public的;
- java中main方法:public static void main(String[] args) {…};
- Unit:相当于java的void;
- def:defined的缩写,用来标识方法;
- args:方法的参数名;
- Array[String]:Array代表数组,[]是用来标识泛型,[String]代表数组中存储是String类型的属性;
- scala一行如果只写一个语句,那么;可以省略。如果一行写多个语句,那么;不能省略;
第2章、变量和数据类型
注释
- scala中的注释和java中的注释完全一样;
标识符
- Java中标识符的定义规范:只能是字母、数字、下划线、美元符号,首字母不能是数字;
- scala中标识符的定义规范:只能是字母、数字、下划线、特殊符号,首字母不能是数字。特殊符号不推荐程序员使用,是scala内部使用的;
- java中定义变量的时候一般使用驼峰命名原则,scala也是推荐驼峰原则
变量
- Java定义变量:类型 变量名 = 值;
- scala中定义变量:val/var 变量名:类型 = 值;
- val与var的区别:
- val定义的变量类似java final的,不能被重新赋值;
- var定义的变量可以被重新赋值;
- scala在定义变量的时候,变量类型可以省略,scala会自动推断变量类型
- scala在定义变量的时候必须初始化;
字符串
- Java中如何获取字符串:
- 通过new的方式:new String("…");
- 通过 “” 包裹:"…";
- 通过连接符+:“aa” + “bb”;
- 通过一些方法获取:toString、subString……;
- scala中获取字符串:
- 通过new的方式:new String("…");
- 通过 “” 包裹:"…";
- 通过连接符+:“aa” + “bb”;
- 通过一些方法获取:toString、subString……;
- 通过插值表达式:s"aa ${外部变量/表达式}";
- 通过三引号的方式:"""…""" [后续主要用来写SQL语句];
键盘输入
- scala键盘输入:StdIn.readLine/readInt/readBoolean;
- scala从文件中读取数据:Source.fromFile(path).getLines;
数据类型:
- Java数据类型:
- 基本数据类型:byte、short、int、long、char、boolean、float、double;
- 应用数据类型:类、接口、数组;
- Scala数据类型:
- Any:所有类的父类,类似java Object
- AnyRef:引用类型
- String、集合、数组、java class、scala class
- Null:是所有引用类型的子类,也有一个实例null,null一般用于给变量赋予初始值,在给变量赋初始值的时候,变量类型不能省略
- AnyVal:值类型
- Byte、Short、Int、Char、Long、Float、Double、Boolean
- Stringops:就是对java String的扩展
- Unit:相当于对java String的扩展
- Nothing:所有类型的子类。是scala内部使用,开发人员不能创建Nothing对象
类型转换
- 数字与字符串的转换:
- 数字转字符串:
- toString;
- 插值表达式;
- 通过 + 拼接;
- 字符串转数字:
- toXXX方法转换;
- 数字和数字的转换:
- 低精度转高精度[自动转换]:Int->Long;
- 高精度转低精度[通过toXXX方法]:Long->Int;
第3章、运算符
Java中的运算符
- 算术运算符:+、-、*、/、++、–;
- 关系运算符:>、<、>=、<=、!=、==;
- 逻辑运算符:&&、||、!;
- 赋值运算符:+=、-=、*=、/=、=;
- 位运算符:<<、>>、>>>、&、|…;
- 三元运算符:布尔表达式 ? 表达式1 : 表达式2;
Scala中没有++、–、三元运算符
- 算术运算符:+、-、*、/;
- 关系运算符:>、<、>=、<=、!=、==;
- 逻辑运算符:&&、||、!;
- 赋值运算符:+=、-=、*=、/=、=;
- 位运算符:<<、>>、>>>、&、|…;
scala中运算符其实是一个个的方法,scala中方法的调用的方式:
- 对象.方法名(参数值, …);
- 对象 方法名 (参数值, …) 如果方法的参数只有一个,()可以省略
第4章、流程控制
块表达式
- 块表达式:有{ }包裹的一块代码称之为块表达式,块表达式的结果值为{ }中最后一个表达式的结果值;
if
- Scala中流程控制有:
- 分支:if
- 循环:for、while、do-while
- scala中没有switch流程控制
- if的使用:
- 单分支:if(布尔表达式) {…}
- 双分支:if(布尔表达式) {…} else {…}
- 多分支:if(布尔表达式) {…} else (布尔表达式) {…} else {…}
for
- for的两个重要方法:
- to方法:start.to(end) 生成的集合是左右闭合的集合;
- until方法:start.until(end)生成的集合是左闭右开的集合;
- for的使用:
- for基本语法:for(变量名 <- 数组/集合/表达式) {…};
- 守卫:for(变量名 <- 数组/集合/表达式 if (布尔表达式)) {…};
- 步长:for(变量名 <- start to end by step if (布尔表达式) ) {…};
- 嵌套循环:for(变量名 <- 数组/集合/表达式; 变量名2 <- 数组/集合/表达式; …) {…};
- 嵌套循环 + 守卫:for(变量名 <- 数组/集合/表达式 if (布尔表达式); 变量名2 <- 数组/集合/表达式 if (布尔表达式); …) {…};
- 嵌入变量:for(变量名 <- 数组/集合/表达式 if (布尔表达式); 变量名 = 值; 变量名2 <- 数组/集合/表达式 if (布尔表达式); …) {…};
- yield表达式:for(变量名 <- 数组/集合/表达式) yield {…};
while和do-while
- scala的while、do-while用于与java完全一样
- while和do-while的区别:
- while是先判断后执行;
- do-while是先执行后判断;
break和continue
- break:结束当前循环;
- continue:结束本次循环;
- scala中没有break和continue;
- scala实现break:
- 导入包:import scala.util.control.Breaks._;
- 使用breakable与break方法实现;
第5章、函数式编程
方法定义
- 方法语法:def 方法名(参数名: 类型, …): 返回值类型 = {方法体};
- scala方法可以定义在任何地方;
方法简化
- 如果将方法体块表达式的结果值作为方法的返回值,定义方法的时候返回值类型可以省略;
- 如果方法体中有 return 关键字,定义方法的时候返回值类型必须定义;
- 如果方法体只有一行语句,{ }可以省略;
- 如果方法不需要参数,( )可以省略;
- 如果定义方法的时候有( ),调用方法的时候( )可有可无;
- 如果定义方法的时候没有( ),调用方法的时候( )也不能带上;
- 如果方法不需要返回值,那么=可以省略,=与{ }不能同时省略;
方法参数
- 方法的参数可以给默认值:def 方法名(参数名: 参数类型 = 默认值, …): 返回值类型 = {方法体}
- 有默认值的参数一般放在参数列表的后面;
- 带名参数:在调用方法的时候指定将值传递给方法的哪个参数
- 方法名(参数名 = 值);
- 可变参数:传递的参数值的个数不确定
- 可变参数必须放在参数列表最后面,不能与默认值参数一起使用;
- def 方法名(参数名: 参数类型*) = {方法体};
- 数组/集合不能直接传递给可变参数,只能通过 数组名/集合名:_* 的形式传给可变参数
函数定义
- 函数定义语法:val 函数名 = (参数名: 参数类型, …) => {函数体}
- 行数的返回值就是函数体块表达式的结果值;
- 函数的简化:如果函数体只有一行语句,{ }可以省略;
- 方法就是函数,函数也是对象;
方法与函数的区别
- 存储位置不同:
- 函数是对象存储在堆里面;
- 方法存储在方法区;
- 方法如果定义在 object/class 中可以构成重载,但是函数不可以
- 方法定义在方法里其实就是函数,不可以重载;
- 方法可以转换成函数:方法名_
高阶函数
- 以函数作为方法的参数或者是返回值的方法/函数称之为高阶函数;
高阶函数的简化
- 直接将函数本身作为值传递;
- 函数的参数类型可以省略;
- 如果函数的参数在函数体中只使用了一次,那么可以用_代替
- 如果函数中参数的使用顺序与参数的定义顺序不一致,不能使用_代替;
- 如果函数参数只有一个,并且在函数体中没有做任何操作,直接返回函数参数本身的时候,不能用_代替;
- 如果函数的参数只有一个,函数参数列表的( )可以省略;