1.惰性加载:
在企业的大数据开发中,有时候会编写非常复杂的SQL语句,这些SQL语句可能有几百行甚至上千行。这些SQL语句,如果直接加载到JVM中,会有很大的内存开销。如何解决?
当有一些变量保存的数据较大时,但是不需要马上加载到JVM内存。可以使用惰性赋值来提高效率。
语法格式:
lazy val/var 变量名 = 表达式
2.scala提供多种定义字符串的方式,将来我们可以根据需要来选择最方便的定义方式。
使用双引号 : val/var 变量名 = “字符串”
使用插值表达式(有效避免大量字符串的拼接): val/var 变量名 = s"${变量/表达式}字符串"
使用三引号: 如果有大段的文本需要保存,就可以使用三引号来定义字符串。例如:保存一大段的SQL语句。三个引号中间的所有字符串都将作为字符串的值。
val/var 变量名 = """字符串1字符串2"""
eg. val sql = """select | * | from | t_user | where | name = "zhangsan""""
println(sql)
3. 运算符
scala中没有,++、--运算符
与Java不一样,在scala中,可以直接使用==、!=进行比较,它们与equals方法表示一致。而比较两个对象的引用值,使用eq
eg. val str1 = "abc"val str2 = str1 + ""str1 == str2 //truestr1.eq(str2) //false
4.
val b:Int = null
scala会解释报错:
Null类型并不能转换为Int类型,说明Null类型并不是Int类型的子类
5. 条件表达式,与Java不一样,有返回值
在scala中,没有三元表达式,可以使用if表达式替代三元表达式
eg. val result = if(sex == "male") 1 else 0
块表达式- scala中,使用{}表示一个块表达式- 和if表达式一样,块表达式也是有值的- 值就是最后一个表达式的值
6.中缀调用法: for(i <- 1 to 10) ...
7.嵌套循环:for(i <- 1 to 3; j <- 1 to 5) {print("*");if(j == 5) println("")}
8.break和continue
- 在scala中,类似Java和C++的break/continue关键字被移除了- 如果一定要使用break/continue,就需要使用scala.util.control包的Break类的**breakable**和**break**方法。
实现break
**用法**
- 导入Breaks包`import scala.util.control.Breaks._`- 使用breakable将for表达式包起来- for表达式中需要退出循环的地方,添加`break()`方法调用
**示例**使用for表达式打印1-100的数字,如果数字到达50,退出for表达式
**参考代码**
// 导入scala.util.control包下的Breakimport scala.util.control.Breaks._breakable{ for(i <- 1 to 100) { if(i >= 50) break() else println(i) }}
实现continue**用法**continue的实现与break类似,但有一点不同:> 实现break是用breakable{}将整个for表达式包起来,而实现continue是用breakable{}将for表达式的循环体包含起来就可以了
**示例**
打印1-100的数字,使用for表达式来遍历,如果数字能整除10,不打印
// 导入scala.util.control包下的Break import scala.util.control.Breaks._for(i <- 1 to 100 ) { breakable{ if(i % 10 == 0) break() else println(i) }}
9.方法参数:
默认参数: 在定义方法时可以给参数定义一个默认值。// x,y带有默认值为0 def add(x:Int = 0, y:Int = 0) = x + yadd() //0带名参数: 在调用方法时,可以指定参数的名称来进行调用。def add(x:Int = 0, y:Int = 0) = x + yadd(x=1) //1
变长参数: 如果方法的参数是不固定的,可以定义一个方法的参数是变长参数。scala> def add(num:Int*) = num.sumadd(1,2,3,4,5) //15
10. 方法调用方式
在scala中,有以下几种方法调用方式,- 后缀调用法- 中缀调用法- 花括号调用法- 无括号调用法在后续编写spark、flink程序时,我们会使用到这些方法调用方式。
后缀调用法:这种方法与Java没有区别。对象名.方法名(参数)scala> Math.abs(-1)res3: Int = 1
中缀调用法:**语法** 对象名 方法名 参数。1 to 10操作符即方法。1 + 1scala> Math abs -1 res4: Int = 1> 如果有多个参数,使用括号括起来
花括号调用法语法Math.abs{ // 表达式1 // 表达式2}> 方法只有一个参数,才能使用花括号调用法scala> Math.abs{ println("请绝对值") -10}res13: Int = 10
无括号调用法:如果方法没有参数,可以省略方法名后面的括号。def m3()=println("hello")m3 //调用时不用加括号
11.方法和函数的区别
- 方法是隶属于类或者对象的,在运行时,它是加载到JVM的方法区中- 可以将函数对象赋值给一个变量,在运行时,它是加载到JVM的堆内存中- 函数是一个对象,继承自FunctionN,函数对象有apply,curried,toString,tupled这些方法。方法则没有
12.定长数组和变长数组:
# 定长数组:- 定长数组指的是数组的**长度**是**不允许改变**的- 数组的**元素**是**可以改变**的
// 通过指定长度定义数组val/var 变量名 = new Array[元素类型](数组长度)// 用元素直接初始化数组val/var 变量名 = Array(元素1, 元素2, 元素3...)
# 变长数组:变长数组指的是数组的长度是可变的,可以往数组中添加、删除元素创建变长数组,需要提前导入ArrayBuffer类`import scala.collection.mutable.ArrayBuffer
创建空的ArrayBuffer变长数组,语法结构:val/var a = ArrayBuffer[元素类型]()创建带有初始元素的ArrayBufferval/var a = ArrayBuffer(元素1,元素2,元素3....)
13.for(i <- 0 until a.length) prinln(a(i)) //until关键字
14. val a = Array(1,2,3,4,5)
a.sum, a.max, a.min, a.sorted, a.sorted.reverse
15.元组
使用括号来定义元组val/var 元组 = (元素1, 元素2, 元素3....)使用箭头来定义元组(元组只有两个元素)val/var 元组 = 元素1->元素2
注:如果用val修饰元组变量,则其里面的所有元素都是不能被重新赋值! 这点和数组不同。
16. 列表:
列表是scala中最重要的、也是最常用的数据结构。List具备以下性质:- 可以保存重复的值- 有先后顺序在scala中,也有两种列表,一种是不可变列表、另一种是可变列表不可变列表就是列表的元素、长度都是不可变的。**语法**使用`List(元素1, 元素2, 元素3, ...)`来创建一个不可变列表,语法格式:val/var 变量名 = List(元素1, 元素2, 元素3...)使用`Nil`创建一个不可变的空列表val/var 变量名 = Nil使用`::`方法创建一个不可变列表val/var 变量名 = 元素1 :: 元素2 :: Nil> 使用**::**拼接方式来创建列表,必须在最后添加一个Nil
17. list获取列表的前缀和后缀:
scala> val a = List(1,2,3,4,5)a: List[Int] = List(1, 2, 3, 4, 5)
scala> a.take(3)res56: List[Int] = List(1, 2, 3)
scala> a.drop(3)res60: List[Int] = List(4, 5)
18.list拉链与拉开
拉链:使用zip将两个列表,组合成一个元素为元组的列表
拉开:将一个包含元组的列表,解开成包含两个列表的元组
scala> val a = List("zhangsan", "lisi", "wangwu")a: List[String] = List(zhangsan, lisi, wangwu)scala> val b = List(19, 20, 21)b: List[Int] = List(19, 20, 21)scala> a.zip(b)res1: List[(String, Int)] = List((zhangsan,19), (lisi,20), (wangwu,21))
scala> res1.unzipres6: (List[String], List[Int]) = (List(zhangsan, lisi, wangwu),List(19, 20, 21))
19.方法中的函数参数,如果该函数的参数在方法体中只出现一次,且没有其他的任何嵌套调用,则该函数的参数部分可以省略,且其表达式中用到参数时,可以用下划线代替。
20.println("-" * 15) ,结果:打印出来15个减号
21.当我们定义一个样例类,编译器自动帮助我们实现了以下几个有用的方法:
apply方法 // 不用new关键字,构建对象
toString方法 //eg. Person(张三,20)
equals方法 //比较2个对象的所有成员变量是否相等(如果比较引用是否相等,用eq)
hashCode方法
copy方法 //可使用带名参数拷贝一个对象的所有成员变量到另一个对象。
22. 非变、协变、逆变:详见代码
23.方法格式和函数格式:
方法: def 方法名(参数:参数类型, 参数:参数类型 ...) : 返回值类型 = { 方法体 }
函数: val/var 函数变量名 : 【(参数类型, 参数类型, ...) => 返回值类型】 = (参数:参数类型, 参数:参数类型 ...) => { 函数体 } //函数可以省略返回值类型,scala会根据函数体自动判断,即 红色字体部分可以省略;如果函数体只有一个表达式,可省略花括号。
方法可以转化为函数,反过来不行: eg. val func = add _ //将add方法转化为函数,赋值给变量func
eg1. val func: Int => String = (num:Int) => "*" * num //用于将数字转换为指定个数的小星星
eg2. scala> var func2 : (Int,Int) => String = (x:Int,y:Int) => x+y+"a" //红色字体部分可以省略
func2: (Int, Int) => String = <function2>
24.scala的actors和akka的actors的区别:
首先actor模型是处理高并发问题的,Akka actors和Scala actors是该模型的两个实现, akka是另一个独立的actor, 比scala自带的强大的多, 当然也是scala写的, 在生产过程中大多数都是使用akka中的actor模型。
转载于:https://www.cnblogs.com/mediocreWorld/p/11483627.html
相关资源:JAVA上百实例源码以及开源项目