大数据系列第四课:scala高阶
来源:互联网 发布:论文:浅析淘宝店的运营 编辑:程序博客网 时间:2024/05/17 22:01
第一阶段:Spark streaming、spark sql、kafka、spark内核原 理(必须有一个大型项目经验);
第二阶段:spark运行的各种环境,各种故障的解决,性能 优化(精通spark内核、运行原理);
第三阶段:流处理、机器学习为鳌头,需要首先掌握前两个 阶段的内容;
跟随王家林老师的零基础讲解,注重动手实战,成为spark高手,笑傲大数据之林!
第一部分:学习笔记
本期内容:
1 Scala模式匹配彻底详解
2 Scala类型系统彻底详解
3 Spark源码阅读及作业
一、模式匹配和类型
(1)模式匹配可以匹配类型、值等
1、值的匹配
def bigData(data:String){data match{case "Spark" =>ptintln("Wow!")case "Hadoop" =>println("OK")case _O =>println(" The others!") //匹配其他形式的字符串}}bigData("Hadoop") //传进Hadoop后,开始遍历匹配,匹配到后,会停止执行bigData("Flink") //匹配其他的形式字符串
模式匹配的时候进行判断
def bigData(data:String){data match{case "Spark" =>ptintln("Wow!")case "Hadoop" =>println("OK")case _ if data =="Flink" =>println("Cool")case _ =>println("Something else")}}bigData("Spark")bigData("Flin") //条件判断,进行分层过滤
用变量名接受了模式匹配输入的内容
def bigData(data:String){data match{case "Spark" =>ptintln("Wow!")case "Hadoop" =>println("OK")case data if data_ =="Flink" =>println("Cool" + data_)case _ =>println("Something else")} //将传进的data赋给变量data_}
2、类型的匹配
import java.io._def exception(e:Exception)e catch{case fileException:FileNotFoundException =>println("File not found:" +fileException)case _:Exception =>ptintln(s"Exception getting thread from excutor SexecutedID",e)}//调用,匹配首先打印Exception,匹配类型exception(new FileNotFoundException("Hello!"))
3、对集合进行匹配
def data(array:Array[String]){array match{case Array("Scala") =>("Scala") //匹配指定数组中的元素case Array(Spark,hadoop,flink) =>println(spark +":" +hadoop+":" +flink)case Array("Spark", _*) =>println("Spark ...")//匹配以某元素开头的元素case _ =>println("Unknown") //匹配其他的数组元素}}data(Array("Spark")data(Array("Scala","Spark"),"Kafka") //匹配将值传给匹配的变量并打印
4、case class
case class person(name:String) //适合并发编程的消息传递
自动生成当前消息的case class的伴生对象case object
(1)case class 相当于Java中bin
(2)自己的实例化,调用伴生对象的apply方法,返回一个实例
//case class Worker(id:String,salary:Double) extends Person(name)case class Person //直接定义Personcase class Worker(name:String,salary:Double) extends Personcase class Student(name:String,score:Double) extends Person//定义函数sayHidef sayHi(person:Person){person match{case Student(name,score) =>println("I am a student:" +name + score)case Worker(name,salary) =>println("I am a Worker:" +name + salary)case _ =>println("Unknown!")}}sayHi(Worker("Spark",32)) //传进参数,匹配变量并接收sayHi(Student("Spark",31))
二、类型参数
1、泛型类、函数
class Person[T](val content:T)class Person[T](val content:T){def getContent(id:T) = id + "_" +content}val p = new Person[String]("Spark") //实例化对象的时候指定泛型类型Stringp.getContent("Scala") //类型控制,这里必须传入String类型
2、类型边界(对类型本身指定边界)
如:大数据Spark工程师,调用spark类型工作,也可以调用其子类型进行工作大数据Spark工程师[ _ <:Spark技能] //这边的上边界就是[Spark技能]。
1.class Pair[T <: Comparable[T]](val first : T,val second : T){ 2. def bigger = if(first.compareTo(second) > 0)first else second 3.} 4.class Pair_Lower_Bound[T](val first:T,val second:T){ 5. def replaceFirst[R >: T](newFirst:R)= new Pair_Lower_Bound[R](newFirst,second) 6.} 7.object Typy_Variables_Bounds { 8. def main(args: Array[String]){ 9. val pair = new Pair("Spark", "Hadoop") 10. println(pair.bigger) 11. } 12.}
上述代码中给泛型类Pair中的类型T一个限定,即类型为T的成员有一个方法为CompareTo,如注释掉的代码会报错,因为不知道first和second的具体类型,无法判定first和second是否有CompareTo,那么就需要对T有一个限定(对变量类型本身的限定)。具体限定为[T<:Comparable[T]],即T类型为Comparable的子类型(如:compareTo),比较的实现为函数bigger。Class replaceFirst[R:>T]说明R类型为T的父类,Pair[T:<ComparableTo[T]]说明T类型为ComparableTo[T]的下界。
3、View Bounds视图界定(没有上下边界的类型)&隐式转换
支持对类型本身就行隐式转换(如:工作时可能出错,将其隐式转换为可以运行的状态,运行结束后再重新恢复原来的状态)将指定的类型进行隐式转换,转换的类型可以作为类型上界、下界。
View Bounds语法:<%
1.class Pair_NotPerfect[T <% Comparable[T]](val first : T,val second : T){ 2. def bigger = if(first.compareTo(second) > 0)first else second 3.} 1.val pair = new Pair_NotPerfect("Spark", "Hadoop") 2.println(pair.bigger) 3. 4.val pairInt = new Pair_NotPerfect(3, 5) //Int -> RichInt 5.println(pairInt.bigger)
试图界定:是指我们可以把具体的传入的T类型的实例转换成Comparable[T]类型,如果comparable[T]类型不是T类型的父类,使用<%的方式可以进行隐式转换。
视图界定与隐式转换的过程:在应用类型T无法满足上界Comparable[T]的时候,使用<%做视图界定,将类型T隐式转换成Comparable[T]的子类型,例如整数类型Int会先变成RichInt类型,RichInt是以Comparable为类型上界的,所以用ComparaTo方法,即RichInt中有ComparaTo方法。
~[K:<% Writable] //K必须为Writeble类型或者隐式转换为其类型,在上下文中注入隐式值,而且注入的过程是自动的。
class Compare[T :Ordering](val n1:T,val n2:T){ //比较数字大小def bigger(implicit ordered: Ordering[T]) if(ordered.Compare(n1,n2)>0)n1 else n2 }//一定存在一个Ordering 的T类型new Compare[Int](8,3),bigger new Compare[String]("Spark","Hadoop").bigger}
[T:Ordering]其中的Ordering为隐式的,也就是Ordering[T];函数bigger中隐式传进一个参数ordered,他是一种上下文界定的方式。
注:String有一个Ordering[String]
Int 有一个Ordered[Int]
[T:Manifest] //实例化数组Array[T]
4、逆变和协变
C[+T]:如果A是B的子类,那么C[A]是C[B]的子类。逆变范围小;
C[-T]:如果A是B的子类,那么C[B]是C[A]的子类。协变范围大;
C[T]:无论A和B是什么关系,C[A]和C[B]没有从属关系。
class Person[+T] //强制定义为协变类型
[Dependence[_]] :表示可以为任何类型 相当于[Dependence[T]]
Manifest:类型分类,上下文界定,有一个Manifest的隐式值,想得到运行时的具体信息,使用Manifest来存储具体的类型,后来演化为ClassTag。
abstract class RDD[T: ClassTag]( @transient private var _sc: SparkContext, @transient private var deps: Seq[Dependency[_]] )T:ClassTag :运行的时候会有更完善的类型进行匹配import scala.reflect{{{ * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*) //elems:可变参数 * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T] * 根据运行时的类型进行完善匹配,只有运行的时候知道其类型,定义的时候不知道 * scala> mkArray(42, 13) * res0: Array[Int] = Array(42, 13) * * scala> mkArray("Japan","Brazil","Germany") * res1: Array[String] = Array(Japan, Brazil, Germany) * }}} *
5、多重界定
(1)T>:A<:B (T同时拥有上界B和下界A,A是B的子类型)
(2)T<:A with B(T为A或者B的子类,with为接口)
(3)T<%A<%B(视图界定,T即可隐式转换为A并且也可转换为B的类型)
(4)T:A:B(上下文界定)
第二部分:
作业:阅读Spark源码 RDD、HadoopRDD、SparkContext、Master、Worker的源码,并分析里面使用的所有的模式匹配和类型参数的内容
/* * 类型参数的泛型 * 定义了newAPIHadoopFile方法,它有三个类型K,V,F * 类型K,V,F使用限定,是这三个类型都是NewInputFormat[K, V]的子类型; * K,V,F的类型上界是NewInputFormat[K, V]; * Hadoop读取文件的时候,限定输入文件的类型为NewInputFormat的子类; * ClassTag[K],ClassTag[V],ClassTag[F]是具有丰富的上下文信息,运行时推断具体的类型。 * implicit隐式转化 * 类型的上界约束 */ def newAPIHadoopFile[K, V, F <: NewInputFormat[K, V]] (path: String) (implicit km: ClassTag[K], vm: ClassTag[V], fm: ClassTag[F]): RDD[(K, V)] = withScope { newAPIHadoopFile( path, fm.runtimeClass.asInstanceOf[Class[F]], km.runtimeClass.asInstanceOf[Class[K]], vm.runtimeClass.asInstanceOf[Class[V]]) } /* * 类型参数的泛型:视图界定(View Bounds) * 定义了rddToSequenceFileRDDFunctions方法,它有两个类型K,V,它们是Writable类型或者被隐式转换为Writable类型 * 带一个参数rdd,它是带有(K, V)类型的RDD * 方法返回一个带有类型(K, V)的SequenceFileRDDFunctions * ClassTag是具有丰富的上下文信息,运行时推断具体的类型。 * implicit隐式转化 */ def rddToSequenceFileRDDFunctions[K <% Writable: ClassTag, V <% Writable: ClassTag]( rdd: RDD[(K, V)]): SequenceFileRDDFunctions[K, V] = { val kf = implicitly[K => Writable] val vf = implicitly[V => Writable] // Set the Writable class to null and `SequenceFileRDDFunctions` will use Reflection to get it implicit val keyWritableFactory = new WritableFactory[K](_ => null, kf) implicit val valueWritableFactory = new WritableFactory[V](_ => null, vf) RDD.rddToSequenceFileRDDFunctions(rdd) } /* * 类型参数的泛型:上下文界定 * 定义了rddToSequenceFileRDDFunctions方法,它有两个类型K,V,它们是Writable类型或者被隐式转换为Writable类型 * K : Ordering : ClassTag 表示存在一个隐式值Ordering[K],上下文界定 * 方法返回一个带有类型[K, V, (K, V)] 的OrderedRDDFunctions * ClassTag是具有丰富的上下文信息,运行时推断具体的类型。 */ @deprecated("Replaced by implicit functions in the RDD companion object. This is " + "kept here only for backward compatibility.", "1.3.0") def rddToOrderedRDDFunctions[K : Ordering : ClassTag, V: ClassTag]( rdd: RDD[(K, V)]): OrderedRDDFunctions[K, V, (K, V)] = RDD.rddToOrderedRDDFunctions(rdd)
- 大数据系列第四课:scala高阶
- 大数据系列第四课:scala基础
- 大数据系列第五课:scala高阶
- 大数据系列第三课:scala中阶
- 大数据系列第一课:scala基础
- 大数据系列第二课:scala基础
- 大数据系列第一课:scala基础
- 大数据系列第三课:scala基础
- 大数据系列第二课:scala基础
- 大数据系列第五课:scala基础
- 大数据系列修炼-Scala课程01
- 大数据系列修炼-Scala课程02
- 大数据系列修炼-Scala课程03
- 大数据系列修炼-Scala课程04
- 大数据系列修炼-Scala课程05
- 大数据系列修炼-Scala课程06
- 大数据系列修炼-Scala课程07
- 大数据系列修炼-Scala课程08
- 《编程导论》课程设计案例
- 两路HDMI信号无压缩编码 回传给电脑
- ifconfig 说明
- graph slam tutorial : g2o 的使用
- iOS百度地图poi检索(基于百度地图2.3.0SDK开发)
- 大数据系列第四课:scala高阶
- 安卓 SharedPreferences 的简单使用
- C# Http请求(WebClient,HttpWebRequest)
- hibernate中联合主键总结_annotation
- Java中,&&与&,||与|的区别
- centos 7 samba
- 关系型数据库基础 one
- java里&&与&的区别
- ios百度地图的使用(基本定位和地理编码)