文章目录
前言
scala为啥如此重要呢?
1、因为Spark是用scala开发的
现在Spark是大数据领域的杀手级应用框架,大小企业中都会在搭建的大数据平台上,大量使用Spark来处理和分析数据,而要想学好Spark,Scala基础知识是必须要掌握的。
2、功能强大且简练,适合大数据处理
Scala将面向对象与函数式编程相结合,语法简洁而富有表达力,并且提供了强大的功能,非常适合用来处理各种数据。
3、能够较好地融合大数据生态圈
Scala是基于JVM的语言,可以与java进行无缝混编,而大数据生态组件大多都是java开发的,因此可以很好的融合到大数据生态圈。
scala基础知识
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ngiq3ro6-1657416900626)(F:\微信公众号\images\spark\scala基础知识.png)]
1、Scala特性
面向对象
Scala是一种存面向对象语言,万物皆对象理念贯彻地非常彻底。对象的类型和行为是由类和Trait(特质)来描述的。
函数式编程
Scala也是一种函数式语言,函数是头等值,和其他类型(整数、字符串)处于同一地位,函数可以被当作参数进行传递,也可以被当作返回值返回,还可以在函数中定义函数等。
静态类型
Scala语言的类型判断是在运行前做的,即通过编译时检查,保证代码的安全性和一致性,并且使得开发者可以不去额外定义重复的类型信息,代码看起来更加整洁易读。
Scala是以JVM为目标运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言。
扩展性
Scala提供了很多独特的语言机制,可以以库的形式轻易无缝添加新的语言结构。
2、表达式
在Scala中,一切皆为表达式。表达式语法,使得代码非常简洁易读,并且对函数式编程非常友好,因此Scala非常推崇表达式语法。
在Scala中,{}块包含一系列表达式,其结果也是一个表达式,块中最后一个表达式的值就是其值。在java中使用void来声明无返回值的方法,而在Scala里,会返回一个特定的值Unit,表示忽略方法返回值。
3、方法与函数
在scala中,方法和函数的最大区别在于:这个函数是否在类中定义,在类中定义就是方法,方法是类的一部分;函数则是一个完整对象,可以赋值给一个变量。
方法转函数
方式1:显示转化
方法指向的表达式,又重新赋值给了一个函数变量,称为显示转化。
val function1: (Int) => Int = m
方式2:隐式转化
通过偏应用函数的方式,将方法转化为一个新的函数,称为隐式转化。
// 方法名称m后面紧跟一个空格和下划线
val function1 = m _
4、模式匹配
模式匹配是检查某个值是否匹配某个模式的机制。是Java中Switch语句的升级版,可以替代一系列的if else语句。
常用的模式匹配有:常量模式、变量模式、通配符模式、类型模式、case class模式、模式守卫、Option模式
常量模式
仅匹配自身,任何字面量都可以作为常量。
//模式匹配结果作为函数返回值
def patternShow(x : Any) = x match {
//常量模式
case 1 => "1"
case true => "真"
case "test" => "字符串"
case null => "null值"
case Nil => "空列表"
}
变量模式
//模式匹配结果作为函数返回值
def patternShow(x : Any) = x match {
//变量模式
case x => "变量"
}
通配符模式
//模式匹配结果作为函数返回值
def patternShow(x : Any) = x match {
//通配符模式
case _ => "通配符"
}
注意:
1、变量模式和通配符模式都可以匹配任意对象,不同的是变量模式匹配成功后,该变量中会存储匹配成功的值,在后续的代码中还可以引用,而通配符模式匹配成功后,不能再引用匹配到的值。
2、模式匹配是按顺序匹配的,变量模式和通配符模式要写在表达式的最后面。
类型模式
可以匹配变量的类型
//类型模式
def typePattern(t : Any) = t match {
case t : String => "String"
case t : Int => "Intger"
case t : Double => "Double"
case _ => "Other Type"
}
case class模式
case class模式,又称构造器模式,直接在case语句后接类构造器,匹配的内容放置在构造器参数中。
//定义一个Person实例
val p = new Person("xiaoming",30)
//case class 模式
def constructorPattern(p : Person) = p match {
case Person(name,age) => "name =" + name + ",age =" + age
case _ => "Other"
}
模式守卫
使用模式守卫,在模式后面加上if判断语句,让匹配更加具体。
//模式匹配结果作为函数返回值
def patternShow(x : Any) = x match {
//模式守卫
case x if(x == 5) => "守卫"
//通配符模式
case _ => "通配符"
}
Option模式
Scala为可选值定义一个名为Option的标准类型,一个Option实例的值:要么是Some类型的实例,要么是None对象。
class OptionDemo {
val map = Map (("a",18),("b",81))
//get方法返回的类型就是Option[Int]
map.get("b") match {
case some(x) => println(x)
case None => println("不存在")
}
}
5、Scala Trait(特质)
Scala Trait相当于Java的接口,比接口的功能更加强大。最大是区别在于,它还可以定义属性和方法的实现。
一般情况下,Scala类只能够继承单一父类,可以使用with混入多个Trait。如果一个类没有父类,那么它混入的第一个特质需要使用extends关键字,之后混入的使用with。
Trait的定义就是使用trait关键字。
6、集合操作
常用集合
常用的集合有List,Set,Map,元祖,Option,下面就来看下它们的创建方式。
// 定义整型 List,其元素以线性方式存储,可以存放重复对象。
val x = List(1,2,3,4)
// 定义 Set,其对象不按特定的方式排序,并且没有重复对象。
val x = Set(1,3,5,7)
// 定义 Map,把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。
val x = Map("one" -> 1, "two" -> 2, "three" -> 3)
// 创建两个不同类型元素的元组,元组是不同类型的值的集合
val x = (10, "Bigdata")
// 定义 Option,表示有可能包含值的容器,也可能不包含值。
val x:Option[Int] = Some(5)
7、数据源
Scala可以通过Source类读取数据源。
import scala.io.Source
object ReadFile {
//读取ClasPath下的配置文件
val file = Source.fromInputStream(this.getClass.getClassLoader.getResourceAsStream("app.conf"))
//一行一行读取文件,getLines()表示读取文件所有行
def readLine: Unit ={
for(line <- file.getLines()){
println(line)
}
}
//读取网络上的内容
def readNetwork: Unit ={
val file = Source.fromURL("http://www.baidu.com")
for(line <- file.getLines()){
println(line)
}
}
//读取给定的字符串-多用于调试
val source = Source.fromString("test")
}
8、隐式转换
隐式转换可以实现某种类型的对象转换为另一种类型的对象。例如,java和scala集合之间的互相转换,转换后可以调用转换后类型的方法。
隐式转换的前提条件:引入scala.collection.JavaConversions类中相应的隐式转化方法。
import scala.collection.JavaConversions._
scala.collection.Iterable <=> java.lang.Iterable
scala.collection.Iterable <=> java.util.Collection
scala.collection.Iterator <=> java.util.{ Iterator, Enumeration }
scala.collection.mutable.Buffer <=> java.util.List
scala.collection.mutable.Set <=> java.util.Set
scala.collection.mutable.Map <=> java.util.{ Map, Dictionary }
scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap
scala.collection.Seq => java.util.List
scala.collection.mutable.Seq => java.util.List
scala.collection.Set => java.util.Set
scala.collection.Map => java.util.Map
java.util.Properties => scala.collection.mutable.Map[String, String]
注意:
<=> :表示可以互相转换
=> :表示只能单向转换
9、正则匹配
通过实例展示在scala中正则代码怎么写:
// 定义正则
val TEST_REGEX = "home\\*(classification|foundation|my_tv)\\*[0-9-]{0,2}([a-z_]*)".r
//正则匹配: 其中path是用来匹配的字符串
TEST_REGEX findFirstMatchIn path match {
case Some(p) => {
//获取TEST_REGEX中的第一个括号里正则片段匹配到的内容
launcher_area_code = p.group(1)
//获取TEST_REGEX中的第二个括号里正则片段匹配到的内容
launcher_location_code = p.group(2)
}
}
10、异常处理
1. java和scala捕获异常方式不同
java是通过多个catch来捕获不同类型的异常,而scala是通过一个catch子句,加上模式匹配的类型来捕获不同类型异常的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Srr504ej-1657416900628)(F:\微信公众号\images\spark\exception.jpg)]
2. Scala没有checked异常
在java中,非运行时异常在编译器会被强制检查的,要么try catch处理,要么使用throws将异常抛给调用者处理。在scala中,不支持检查型异常,而是使用函数式结构和强类型来减少对异常以及处理的依赖。
3. Scala在throw异常时是由返回值的
在scala的设计中,所有表达式都是有返回值的。throw也是表达式,自然也是有返回值的,它的返回值是Nothing。Nothing类型是所有类型的子类型,因此throw表达式可以出现在任意位置,不会影响类型推断。
11、类型层级
在scala中,所有值都是有类型的,包括数值型值和函数。Scala有自己的类型层级:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pzdemyu7-1657416900629)(F:\微信公众号\images\spark\level.jpg)]
Any是scala的顶级类,包含两个子类,AnyVal和AnyRef,其中AnyVal是所有值类型的父类。其中包含一个特殊的值Unit;AnyRef是所有引用类型的父类,包含两个比较特殊的底层子类型,一个是null,它是所有引用类型的子类型,可以赋值给任何引用类型变量,另一个是Nothing,它是所有类型的子类,因此既可以赋值给引用类型变量,亦可以赋值给值类型变量。
12、基本数值类型转换
在scala中,通常会自动进行java和scala之间基本数值类型的转换,并不需要单独去处理。
但是当你使用第三方java类库,而且它在代码中接收参数是Object类型,之后又对传入对象的实际数值类型做判断时,通常会失败报错。
原因很简单,第三方java类库,使用java语言编写,它只认得java的类型。当接收参数为Object类型时,scala默认不会转换成java的数值类型,这样当判断对象的具体数值类型时,会出现不认识scala对象类型的异常。
解决方案也很简单,只需要在传入第三方类库方法前,手动包装成java类型即可。
//由于java和scala中的类型短名称重名,为避免歧义,进行了重命名
import java.lang.{Long => JLong, Double => JDouble}
//conn为数据库连接,sql为要执行的SQL语句
queryRunner.update(conn, sql, new JLong(1L), new JDouble(2.2))
结语
以上就是scala中最常用到的一些基础知识点了,要想在Spark的学习道路上更近一步,这些知识是必须要掌握的。
好了,今天的分享到这里结束了,咱们下期见!
-------------- end ----------------
微信公众号:扫描下方二维码
或 搜索 笑看风云路
关注,获取更多干货!