- 默认导入的包
- Scala 中默认导入 java.lang 包、Scala 包、Scala.Predef 类
- Java 默认导入 java.lang 包
- 特质 trait 可以类比 Java 中的接口,但是又和接口非常不一样
- Java 中称为类实现了接口,Scala 中称为混入了特质
- 和 Java 中接口不同,Scala 中的特质可以包含带有方法体的方法
5. Scala 中的模式匹配
Scala 的模式匹配包括了一系列的备选项,每个替代项以关键字大小写为单位,每个替代方案包括一个模式或多个表达式,如果匹配将进行计算,箭头符号 => 将模式与表达式分离
Scala中的模式匹配类似于Java中的switch语法,但是更加强大。 模式匹配语法中,采用match关键字声明,每个分支采用case关键字进行声明,当需要匹配时,会从第一个case分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹配不成功,继续执行下一个分支进行判断。如果所有case都不匹配,那么会执行case _ 分支,类似于Java中default语句。
obj match{
case 1 => "one"
case 2 => "two"
case 3 => "three"
case _ => default
}
6. case class 和 class 的区别
case class 是一个样例类:
样例类是一种不可变切可分解类的语法糖,也就是说在构建的时候会自动生成一些语法糖,具有以下几个特点:
- 自动添加与类名一致的构造函数(也就是半生对象,通过apply方法实现),也就是说在构造对象的时候不需要使用new关键字
- 样本类中的参数默认是val关键字,不可以修改
- 默认实现了toString,equals,hashcode,copy方法
- 样本类可以通过==来比较两个对象,不在构造方法内地二属性不会用在比较上
class是一个类:
class在构造对象的时候需要使用new关键字才可以。
7. 谈谈 Scala 中的隐式操作
(1)隐式变量
为函数提供隐式参数(常和柯里化结合使用)
def method(name:String)(prefix:String="DEFAULT") = print(prefix + name)
implicit prefix:String="DEFAULT"
def method(name:String)(implicit prefix:String) = print(prefix + name)
(2)隐式函数
给函数类型的参数提供默认值,
同一作用域下同一种类型只能出现一个
应用:隐式类型转换
def main(args: Array[String]): Unit = {
//隐式函数,默认将字符串类型转换为整数类型
//同一作用域下同一类型只能出现一个,也就是说该作用域下不能再将字符串类型隐式转换成其他类型
implicit def fsi(v:String):Option[Int] = {
val regexInt = "\\d+".r
if (regexInt.pattern.matcher(v).matches){
Some(v.toInt)
}else{
Option.empty
}
}
val a:Option[Int]="abc"
println(a)
}
(3)隐式类
隐式扩展唯一构造参数指定的类型的功能
//功能:如果数组类型为Int类型则求和,否则输出字符串,以空格为间隔符
implicit class ArrExt[T](arr:Array[T]){
def c()={
if (arr.isInstanceOf[Array[Int]] ){
arr.asInstanceOf[Array[Int]].sum
}else if(arr.isInstanceOf[Array[String]]){
arr.asInstanceOf[Array[String]].mkString(" ")
}else{
throw new RuntimeException("unsupported array type")
}
}
}
def main(args: Array[String]): Unit = {
println(Array(1, 2, 5).c())
println(Array("aa", "bb", "cc").c())
}
(4)隐式对象
扩展功能
//功能:根据传入的参数值类型自动实现对应类型的函数
def main(args: Array[String]): Unit = {
trait A[T]{
def combine(arr:Array[T]):T
def empty:T
}
implicit object StrArrA extends A[String] {
override def combine(arr: Array[String]): String = arr.mkString(",")
override def empty: String = ""
}
implicit object IntArrA extends A[Int] {
override def combine(arr: Array[Int]): Int = arr.sum
override def empty: Int = 0
}
def combine[T](arr:Array[T])(implicit a:A[T]) = {
if (arr.isEmpty){
a.empty
}else{
a.combine(arr)
}
}
val arrStr: Array[String] = Array("aa", "bb", "cc")
val arrInt: Array[Int] = Array(1, 2, 3)
println(combine(arrStr))
println(combine(arrInt))
}
8. Scala 中的偏函数和偏应用函数
偏函数(Partial Function)
是一个数学概念它不是"函数"的一种, 它跟函数是平行的概念。Scala中 的 Partia Function是一个 Trait,其的类型为 PartialFunction[A,B],其中接收一个类型为 A 的参数,返回一个类型为 B 的结果。
通常结合模型匹配使用
scala> val pf:PartialFunction[Int,String] = {
| case 1=>"One"
| case 2=>"Two"
| case 3=>"Three"
| case _=>"Other"
| }
pf: PartialFunction[Int,String] = <function1>
scala> pf(1)
res0: String = One
scala> pf(2)
res1: String = Two
scala> pf(3)
res2: String = Three
scala> newPF(4)
res3: String = Other
偏函数内部有一些方法,比如isDefinedAt、OrElse、 andThen、applyOrElse等等。
偏应用函数(Partial Applied Function)
也叫部分应用函数,跟偏函数(Partial Function)从英文名来看只有一字之差,但他们二者之间却有天壤之别。
部分应用函数, 是指一个函数有n个参数, 而我们为其提供少于n个参数, 那就得到了一个部分应用函数,类似于柯里化
scala> def add(x:Int,y:Int,z:Int) = x+y+z
add: (x: Int, y: Int, z: Int)Int
scala> def addX = add(1,:Int,:Int) // x 已知
addX: (Int, Int) => Int
scala> addX(2,3)
res1: Int = 6
scala> addX(3,4)
res2: Int = 8
scala> def addXAndY = add(10,100,_:Int) // x 和 y 已知
addXAndY: Int => Int
scala> addXAndY(1)
res3: Int = 111
scala> def addZ = add(:Int,:Int,10) // z 已知
addZ: (Int, Int) => Int
scala> addZ(1,2)
res4: Int = 13
9. Scala 中的元组
- Scala中的元组是一个固定数量的组合,本体可以作为一个参数传递
- 元组可以容纳不同类型的数据
- 元组是不可变的
- 元组是有上限的,最多能有22个元素
10. trait(特质)和 abstract class(抽象类)的区别
- 一个类只能继承一个抽象类,但是可一个通过 with 关键字继承多个特质
- 抽象类有带参数的构造函数,特质不行(如 trait t(i: Int) {},这种声明是错误的)。
- 一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。所以优先使用特质。如果需要构造函数参数,使用抽象类
11. ArrayBuffer 和 Array 的区别
- Array 里面可以放数字、字符串、布尔值、以及对象和数组等,ArrayBuffer 放 0 和 1 组成的二进制数据
- Array 存放在堆中,ArrayBuffer 则把数据存放在栈中(所以取数据时后者快)
- ArrayBuffer 初始化后固定大小,数组则可以自由增减(其实是生成了一个新数组)
现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。
分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!