BigData-22:Scala基础

Scala语言简介

Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。它也能运行于CLDC配置的Java ME中。目前还有另一.NET平台的实现,不过该版本更新有些滞后。Scala的编译模型(独立编译,动态类加载)与Java和C#一样,所以Scala代码可以调用Java类库(对于.NET实现则可调用.NET类库)。Scala包括编译器和类库,以及BSD许可证发布。
学习Scala编程语言,为后续学习Spark奠定基础。

Scala数据类型

① 数值类型:Byte,Short,Int,Long,Float,Double
Byte: 8位有符号数字,从-128 到 127
Short: 16位有符号数据,从-32768 到 32767
Int: 32位有符号数据
Long: 64位有符号数据

例如:
val a:Byte = 10
a+10
得到:res9: Int = 20
这里的res9是新生成变量的名字

val b:Short = 20
a+b
**注意:**在Scala中,定义变量可以不指定类型,因为Scala会进行类型的自动推导。

② 字符类型和字符串类型:Char和String
对于字符串,在Scala中可以进行插值操作
在这里插入图片描述
③ Unit类型:相当于Java中的void类型

在这里插入图片描述
④Nothing类型:一般表示在执行过程中,产生了Exception

在这里插入图片描述

Scala语法基础

一、循环语句
1、类似Java:for、while、do…while
2、使用foreach进行迭代(循环)

val list = List("Mary", "Tom", "Mike")
		
		//for的第一种写法
		for (elem <- list) {
			println(elem)
		}
		System.out.println("************************")
		
		// 第二种写法
		// 加上判断条件,打印名字长度大于3的
		for (elem <- list if elem.length() > 3) {
			println(elem)
		}
		System.out.println("************************")
		
		// 第三种写法,使用yield关键字,产生一个新的集合
		// 把list中的每个元素变成大写
		val newList: List[String] = for{
			elem <- list
			s = elem.toUpperCase
		}yield (s)
		
		for (elem <- newList) {
			println(elem)
		}
		System.out.println("************************")
		
		
		// 使用while
		var i = 0
		while (i < list.length){
			println(list(i))
			i += 1
		}
		System.out.println("************************")
		
		var j = 0
		do {
			println(list(j))
			j += 1
		}while(j < list.length)
		System.out.println("************************")
		
		
		// 使用forEach进行迭代
		// foreach和map的区别:foreach没有返回值,map有返回值
		list.foreach(println)

二、Scala的函数参数
1、函数参数的求值策略
(1)call by value 定义: :
对函数实参求值,并且只求一次

(2)call by name 定义: :=>
函数的实参在函数体内部每次用到的时候,都会被求值

(3)复杂点的例子

			5-05	
			x是call by value, y是call by name
			def bar(x:Int,y: => Int):Int = 1
			
			定义一个死循环
			def loop():Int = loop
			
			调用bar函数,哪次会产生死循环?
			1、bar(1,loop)  正常返回1
			2、bar(loop,1)   会产生死循环
			
			分析原因!!

2、Scala中的函数参数的类型
	(1)默认参数
	     def func1(name:String="Tom"):String = "Hello " + name
			
	
	(2)代名参数:应用的场景:当有多个默认参数的时候,通过代名参数可以确定是给哪一个参数赋值
	     def func2(str:String="Good Morning ",name:String="Tom ",age:Int=20)
		 =
		 str + name + " and the age of " + name + " is " + age
		 
		 调用一下
		 func2()
		 func2(name="abcd")  把abcd付给name参数
	
	
	(3)可变参数
		scala> //可变参数

		scala> //求多个数字的和

		scala> def sum(args:Int*) = {
			 |     var result = 0
			 |     for(s <- args) result += s
			 |     result
			 | }
		sum: (args: Int*)Int

		scala> //调用

		scala> sum(1,2,3)
		res4: Int = 6

		scala> sum(1,2,3,4,5)
		res5: Int = 15

三、懒值(lazy值):常量如果是lazy的,他的初始化就会被推迟,推迟到第一次使用该常量的时候

做一点铺垫:Spark的核心是RDD(数据集合),操作数据集合中的数据,需要使用算子(函数、方法)
			算子有两种
			1、Transformation:延时加载,不会触发计算
			2、Action:会触发计算
		scala> //lazy值 懒值

		scala> val x:Int = 10
		x: Int = 10

		scala> val y:Int = x + 1
		y: Int = 11

		scala> //上面的特点是立即执行计算

		scala> lazy val z:Int = x + 1
		z: Int = <lazy>

		scala> //常量z的初始化就会被推迟

		scala> //没 有发计算

		scala> z
		res6: Int = 11

再举一个例子:读文件
	(1)存在的文件
	(2)不存在的文件
		scala> val words = scala.io.Source.fromFile("d:\\temp\\student.txt").mkString
		words: String =
		1 Tom 23
		2 Mary 25
		3 Mike 24
		5 Jone 20
		6 Jerry 21

		scala> lazy val words = scala.io.Source.fromFile("d:\\temp\\student.txt").mkString
		words: String = <lazy>

		scala> words
		res7: String =
		1 Tom 23
		2 Mary 25
		3 Mike 24
		5 Jone 20
		6 Jerry 21

		scala> //读取一个不存在的文件

		scala> lazy val words = scala.io.Source.fromFile("d:\\temp\\aaa.txt").mkString
		words: String = <lazy>

		scala> //不会产生Exception

		scala> words
		java.io.FileNotFoundException: d:\temp\aaa.txt (系统找不到指定的文件。)
		  at java.io.FileInputStream.open0(Native Method)
		  at java.io.FileInputStream.open(FileInputStream.java:195)
		  at java.io.FileInputStream.<init>(FileInputStream.java:138)
		  at scala.io.Source$.fromFile(Source.scala:91)
		  at scala.io.Source$.fromFile(Source.scala:76)
		  at scala.io.Source$.fromFile(Source.scala:54)
		  at .words$lzycompute(<console>:11)
		  at .words(<console>:11)
		  ... 32 elided

		scala>

四、简介:例外:Exception
类似Java:try…catch…finally
在这里插入图片描述
五、数组
1、数组的类型
(1)定长数组:Array
scala> // 定长数组: Array

		scala> val a = new Array[Int](10)
		a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

		scala> val b = new Array[String](5)
		b: Array[String] = Array(null, null, null, null, null)

		scala> val c = Array("Tom","Mary","Mike")
		c: Array[String] = Array(Tom, Mary, Mike)
	
	
	(2)变长数组:ArrayBuffer
			scala> import scala.collection.mutable.ArrayBuffer
			import scala.collection.mutable.ArrayBuffer

			scala> val d = ArrayBuffer[Int]()
			d: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

			scala> //往变长数组中添加元素

			scala> d += 1
			res9: d.type = ArrayBuffer(1)

			scala> d += 2
			res10: d.type = ArrayBuffer(1, 2)

			scala> d += 3
			res11: d.type = ArrayBuffer(1, 2, 3)

			scala> //一次添加多个元素

			scala> d += (10,20,30)
			res12: d.type = ArrayBuffer(1, 2, 3, 10, 20, 30)			
			
			去掉最后的两个元素
			d.trimEnd(2)
			
			scala> //遍历数组

			scala> var a = Array("Tom","Mary","Mike")
			a: Array[String] = Array(Tom, Mary, Mike)

			scala> //使用for语句进行遍历

			scala> for( s<- a) println(s)
			Tom
			Mary
			Mike

			scala> //使用foreach

			scala> a.foreach(print)
			TomMaryMike
			
	解释一下:
	    myArray1.sortWith(_ > _) 
		写完整
		myArray1.sortWith((a,b)=>{if(a>b) true else false})
		
		匿名函数:(a,b)=>{if(a>b) true else false}    ----> 简写:_ > _
		把匿名函数作为了sortWith参数值 -----> 把sortWith叫做高阶函数(Scala中的函数式编程)
		
2、多维数组:和Java一样,通过数组的数组来实现

在这里插入图片描述
下表中为 Scala 语言中处理数组的重要方法,使用它前我们需要使用import Array._引入包。

序号方法和描述
1def apply( x: T, xs: T* ): Array[T]创建指定对象 T 的数组, T 的值可以是 Unit, Double, Float, Long, Int, Char, Short, Byte, Boolean。
2def concat[T]( xss: Array[T]* ): Array[T]合并数组
3def copy( src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int ): Unit复制一个数组到另一个数组上。相等于 Java’s System.arraycopy(src, srcPos, dest, destPos, length)。
4def empty[T]: Array[T]返回长度为 0 的数组
5def iterate[T]( start: T, len: Int )( f: (T) => T ): Array[T]返回指定长度数组,每个数组元素为指定函数的返回值。以上实例数组初始值为 0,长度为 3,计算函数为a=>a+1scala>Array.iterate(0,3(a=>a+1)res1: Array[Int] = Array(0, 1, 2)
6def fill[T]( n: Int )(elem: => T): Array[T]返回数组,长度为第一个参数指定,同时每个元素使用第二个参数进行填充。
7def fill[T]( n1: Int, n2: Int )( elem: => T ): Array[Array[T]]返回二数组,长度为第一个参数指定,同时每个元素使用第二个参数进行填充。
8def ofDim[T]( n1: Int ): Array[T]创建指定长度的数组
9def ofDim[T]( n1: Int, n2: Int ): Array[Array[T]]创建二维数组
10def ofDim[T]( n1: Int, n2: Int, n3: Int ): Array[Array[Array[T]]]创建三维数组
11def range( start: Int, end: Int, step: Int ): Array[Int]创建指定区间内的数组,step 为每个元素间的步长
12def range( start: Int, end: Int ): Array[Int]创建指定区间内的数组
13def tabulate[T]( n: Int )(f: (Int)=> T): Array[T]返回指定长度数组,每个数组元素为指定函数的返回值,默认从 0 开始。以上实例返回 3 个元素:scala> Array.tabulate(3)(a => a + 5)res0: Array[Int] = Array(5, 6, 7)
14def tabulate[T]( n1: Int, n2: Int )( f: (Int, Int ) => T): Array[Array[T]]返回指定长度的二维数组,每个数组元素为指定函数的返回值,默认从 0 开始。

六、映射:就是的对,用Map来表示
scala> //创建一个Map(映射)

	scala> //学生的成绩

	scala> val scores = Map("Tom"->80,"Mary"->85,"Mike"->82)
	scores: scala.collection.immutable.Map[String,Int] = Map(Tom -> 80, Mary -> 85, Mike -> 82)

	scala> //Scala中,映射有两种  1、不可变的Map  2、可变的Map

	scala> //定义一个可变的Map
	scala> //保存学生的语文成绩
	scala> //有不同写法

	scala> val chinese = scala.collection.mutable.Map(("Alice",80),("Bob",95),("Mary",75))
	chinese: scala.collection.mutable.Map[String,Int] = Map(Bob -> 95, Alice -> 80, Mary -> 75)

	scala> //映射的操作
	scala> //1、获取映射中的值
	scala> chinese("Bob")
	res19: Int = 95

	scala> chinese.get("Bob")
	res20: Option[Int] = Some(95)

	scala> //2、获取一个不存在的值

	scala> chinese("Tom")
	java.util.NoSuchElementException: key not found: Tom
	  at scala.collection.MapLike$class.default(MapLike.scala:228)
	  at scala.collection.AbstractMap.default(Map.scala:59)
	  at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
	  ... 32 elided

	scala> //先判断一下 ,key是否存在

	scala> if(chinese.contains("Tom")){
		 |    chinese("Tom")
		 | }else{
		 |    -1
		 | }
	res22: Int = -1

	scala> //可以简写

	scala> chinese.getOrElse("Tom",-1)
	res23: Int = -1

	scala> chinese.getOrElse("Alice",-1)
	res24: Int = 80
	
	scala> //更新映射中的值:必须是可变的映射

	scala> chinese("Bob")
	res25: Int = 95

	scala> chinese("Bob") = 100

	scala> chinese("Bob")
	res27: Int = 100

	scala> //如何进行迭代?类似数组

	scala> //可以使用for ,foreach

	scala> for(s <- chinese) println(s)
	(Bob,100)
	(Alice,80)
	(Mary,75)

	scala> chinese.foreach(println)
	(Bob,100)
	(Alice,80)
	(Mary,75)

七、元组:Tuple
1、复习一下:Tuple在Pig中、在Storm中都用到了
2、Scala的Tuple:是不同类型的值的集合
scala> //Tuple3代表的是有三个元素

	scala> val t2 = Tuple2(2,"World")
	t2: (Int, String) = (2,World)

	scala> //访问Tuple中的元素

	scala> t1.
	_1   _3         copy     hashCode   productArity     productIterator   toString   zipped
	_2   canEqual   equals   invert     productElement   productPrefix     x

	scala> t1._1
	res30: Int = 1

	scala> t1._2
	res31: Double = 3.14

	scala> t1._3
	res32: String = Hello

	scala> //如何遍历Tuple中的元素

	scala> //首先使用productIterator生成再遍历

	scala> t1.productIterator.foreach(println)
	1
	3.14
	Hello

**注意:**要遍历Tuple中的元素,需要首先生成对应的迭代器。不能直接使用for或者foreach。

Scala的面向对象:类似Java

一、面向对象的基本概念
1、封装:类class
2、继承
3、多态

(1)当定义属性是private时候,scala会自动为其生成对应的get和set方法
(2) 如果只希望get方法,不生成set方法,可以将属性定义为val常量
(3)如果希望不能直接被外部类访问(即希望不要生成get和set方法),可以使用private[this]修饰类或者属性

二、定义类:关键字class
举例:创建一个学生类

三、内部类

四、类的构造器:两种
1、主构造器:和类的声明在一起,并且一个类只有一个主构造器
2、辅助构造器:一个类可以有多个辅助构造器,通过关键字this

五、Object对象:相当于Java中的static
1、Object中的内容都是静态的
2、Scala中,没有静态修饰符static
3、如果class的名字,跟object的名字一样,这时候就把这个object叫做类的伴生对象
4、举例
(1)使用object实现单例模式:一个类只有一个对象
如果在Java中,构造器定义为private,提供getInstance方法

	(2)使用App对象:应用程序对象
			好处:可以省略main方法

六、apply方法:可以省略new关键字,根据自己的需要进行初始化
apply方法必须写在伴生对象中
在这里插入图片描述
scala> //创建一个数组

scala> var myarray = Array(1,2,3)   ----> 使用了apply方法
myarray: Array[Int] = Array(1, 2, 3)

scala> //本质就是创建一个Array对象

scala> //省略了new关键字

七、继承:
1、跟Java一样,使用关键字extends
2、抽象类、抽象字段

八、特质(trait):类似Java中的抽象类,并且支持多重继承
本质:就是抽象类,特点:支持多重继承
在这里插入图片描述

九、包和包对象:
包可以包含类、对象和特质,但不能包含函数或者变量的定义。很不幸,这是Java虚拟机的局限。
把工具函数或者常量添加到包而不是某个Utils对象,这是更加合理的做法。Scala中,包对象的出现正是为了解决这个局限。
Scala中的包对象:常量,变量,方法,类,对象,trait(特质),包

在这里插入图片描述

十、scala中文件访问
在这里插入图片描述

Scala的函数式编程:Scala是一个多范式的编程语言

举例:使用Spark执行WordCount
sc是Spark的一个对象,SparkContext这个对象非常重要

sc.textFile("hdfs://bigdata111:9000/input/data.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).collect

一、回顾:Scala中的函数:是头等公民
关键字:def

二、匿名函数:没有名字的函数
scala> //定义一个匿名函数

scala> (x:Int) => x*3
res1: Int => Int = <function1>

scala> //调用匿名函数

scala> //定义一个 数组,把数组中的每个元素乘以3

scala> //Array(1,2,3) 把Array中的每个元素作为x参数值,传递给匿名函数

scala> Array(1,2,3).map((x:Int) => x*3)
res2: Array[Int] = Array(3, 6, 9)

scala> //把(x:Int) => x*3 作为了map的参数值

三、高阶函数(带有函数参数的函数):把一个函数作为另一个函数的参数值
在这里插入图片描述
四、高阶函数示例
在这里插入图片描述
(*)map:相当于一个循环,对某个集合中的每个元素进行操作(就是接受一个函数),返回一个新的集合

	         val numbers = List(1,2,3,4,5,6,7,8,9,10)
			 numbers.map((i:Int)=>i*2)
			 简写 numbers.map(_ * 2)
(*)foreach:相当于一个循环,对某个集合中的每个元素进行操作(就是接受一个函数),不返回结果
         numbers.foreach((i:Int)=>i*2)


(*)filter: 过滤,选择满足条件的数据
		查询能够被2整除的数字
		numbers.filter((i:Int)=> i%2==0) 如果是true,就返回结果

(*)zip: 合并集合
		List(1,2,3).zip(List(4,5,6))


(*)partition: 根据断言(就是条件,通过一个匿名函数来实现)的结果,来进行分区
		举例:把能够被2整除的分成一个区,不能整除的分成另一个区
		numbers.partition((i:Int)=> i%2==0)

(*)find: 查找第一个满足条件(断言)的元素
        查询第一个能够被3整除的数字
		numbers.find(_%3 == 0)

(*)flatten:把嵌套的结构展开
		List(List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9)).flatten

(*)flatMap 相当于 map + flatten
		var myList = List(List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9))
		myList.flatMap(x=> x.map(_*2))
		结果 res16: List[Int] = List(4, 8, 12, 16, 20, 2, 6, 10, 14, 18)
		
		过程 (1)将List(2, 4, 6, 8, 10)和List(1, 3, 5, 7, 9)调用x=> x.map(_*2)
		     (2)再合并成一个List

五、概念:闭包、柯里化

  1. 闭包:就是函数的嵌套,即:
    在一个函数定义中,包含另外一个函数的定义;
    并且在内函数中可以访问外函数中的变量。
scala> //闭包:函数的嵌套

		scala> def mulBy(factor:Double)=(x:Double)=> x* factor
		mulBy: (factor: Double)Double => Double

		scala> //调用

		scala> //1、乘以3的操作,因子=3

		scala> val triple=mulBy(3)
		triple: Double => Double = <function1>

		scala> //值函数

		scala> triple(10)
		res0: Double = 30.0

		scala> //2、乘以0.5的操作 factor=0.5

		scala> val half = mulBy(0.5)
		half: Double => Double = <function1>

		scala> half(10)
		res1: Double = 5.0

在这里插入图片描述
2. 柯里化:Currying
3. 柯里化函数(Curried Function)是把具有多个参数的函数转换为一条函数链,每个节点上是单一参数。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Scala and Spark for Big Data Analytics by Md. Rezaul Karim English | 25 July 2017 | ISBN: 1785280848 | ASIN: B072J4L8FQ | 898 Pages | AZW3 | 20.56 MB Harness the power of Scala to program Spark and analyze tonnes of data in the blink of an eye! About This Book Learn Scala's sophisticated type system that combines Functional Programming and object-oriented concepts Work on a wide array of applications, from simple batch jobs to stream processing and machine learning Explore the most common as well as some complex use-cases to perform large-scale data analysis with Spark Who This Book Is For Anyone who wishes to learn how to perform data analysis by harnessing the power of Spark will find this book extremely useful. No knowledge of Spark or Scala is assumed, although prior programming experience (especially with other JVM languages) will be useful to pick up concepts quicker. What You Will Learn Understand object-oriented & functional programming concepts of Scala In-depth understanding of Scala collection APIs Work with RDD and DataFrame to learn Spark's core abstractions Analysing structured and unstructured data using SparkSQL and GraphX Scalable and fault-tolerant streaming application development using Spark structured streaming Learn machine-learning best practices for classification, regression, dimensionality reduction, and recommendation system to build predictive models with widely used algorithms in Spark MLlib & ML Build clustering models to cluster a vast amount of data Understand tuning, debugging, and monitoring Spark applications Deploy Spark applications on real clusters in Standalone, Mesos, and YARN In Detail Scala has been observing wide adoption over the past few years, especially in the field of data science and analytics. Spark, built on Scala, has gained a lot of recognition and is being used widely in productions. Thus, if you want to leverage the power of Scala and Spark to make sense of big data, this book is for you. The first part introduces you to Scala, helping you understand the object-oriented and functional programming concepts needed for Spark application development. It then moves on to Spark to cover the basic abstractions using RDD and DataFrame. This will help you develop scalable and fault-tolerant streaming applications by analyzing structured and unstructured data using SparkSQL, GraphX, and Spark structured streaming. Finally, the book moves on to some advanced topics, such as monitoring, configuration, debugging, testing, and deployment. You will also learn how to develop Spark applications using SparkR and PySpark APIs, interactive data analytics using Zeppelin, and in-memory data processing with Alluxio. By the end of this book, you will have a thorough understanding of Spark, and you will be able to perform full-stack data analytics with a feel that no amount of data is too big. Style and approach Filled with practical examples and use cases, this book will hot only help you get up and running with Spark, but will also take you farther down the road to becoming a data scientist.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

phial03

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值