第1课 Scala入门与实战笔记总结

第一课:Scala入门
1:Scala的重大价值
2:Scala基础函数入门实战
3:Scala函数入门实战
4:Scala中的Array,Map,Tuple实战
5:综合案例及Spark源码解析

Scala与Java的关系:
一:它们都是基于JVM的,但Scala可以调用Java的任何功能,比如Spark运行在Hadoop上,它可以调用Hadoop上的一切功能。
二:你可以认为Scala它是一个升级版的Java,因为Scala它本身是一门支持面向对象的语言,在Scala中,一切皆对象,它是一门纯面向对象的语言,同时Scala也是面向对象以及函数式结合的语言。


大数据的开发语言是Scala,原因如下:
一:大数据的本身是计算数据,而Scala即有面向对象组织项目工程的能力,又有计算数据的功能。
二:现在大数据事实上的计算标准框架Spark,它是用Scala开发的,因为计算数据,Scala它是函数式编程,它实现算法非常简洁优雅。
例:kafka,它是一个消息中间件,如果外部数据要流进大数据中心,我们一般都要用kafka作适配器,那如果大数据中心的数据流到外部,也是用kafka(如Spark计算的数据要交给HBASE或MySql,期间我们都会用kafka),很多的大数据组件都是用的Scala编写的,SO,如果你想成为一个顶级的大数据开发高手,你一定要掌握Scala。

结果类型转换:
1.5*2 结果res1:Double = 3.0
res1.toInt //按table可以自动补全

Scala中变量的声明:
一:可变变量的声明
var name="Spark" //声明了一个可变变量name,值为Spark,可以将name的值改为Scala:name="Scala"

二:不可变变量的声明
val result = 2+10 //声明了一个不可变的变量result且它的值是12,它的值是不可被改变的,如果你重新给result赋值为13,result=13,此时会报错,因为变量result是不可变变量。

注:Spark RDD中的数据默认都是不可变的。


三:手动指定变量赋值的类型
val age : Int = 0 //指定age不可变变量的类型为Int,值为0
val name : String = null //指定name不可变变量的类型为String,它的默认值是null
注:如果你指定了变量具体的类型,后续对变量赋值时:只能赋值为你指定的类型或者类型的子类型。

四:一行代码同时声明多个变量
val age1, age2,age3 = 0

注意:Scala中,它可以完成基本类型和我们所谓的对象类型的自动转换的操作,在Scala中,基本类型就是对象,比如:10.toLong,在Java中,基本类型是没有这种方法的,但Scala中就有。

Scala中没有这种1++,1--,这种操作符。
比如:var age = 10; age ++ //这样操作是不对的,但是你可以这样做:age+=1

取最小值:
import scala.math._
min(20,4)
结果为4

构建数组:
val array = Array(1,2,3,4)
内部实现:val array = Array.apply(1,2,3,4)

五:if 表达式
val age = 19
if(age>=18) "adult" else "child"
结果String = adult
//注意:Scala中,if表达式是有结果的,但Java中是没有的。

****最后一行的值是整个代码块的返回值:如下****
var buffered = 0;
val result = if(age>=18){
| "audlt"
| buffered = 10
| buffered
}
//结果result:AnyVal = 10

六:循环
0 to element

for(i <- 0 to element) println(i)

//说明:<- 它是个提取符,提取出这个集合Range中的每一个元素并把它的值赋值给i

for(i <- 0 to element if i%2 ==0) {
println(i)
}
//打印出偶数

如何终止循环,因Scala中没有break语句,但Scala中有一个Breaks对象,我们可以使用。
一:导包:import scala.util.control.Breaks._
二:使用
for(i <- 1 to 10){
if(i==4)
break
println(i)
}
结果1 2 3
scala.util.control.BreakControl
//其实此时已经实现了return

七:函数定义:
默认参数
def f3(param1:String,param2:Int=30)=param1+param2
f3("Spark")
值:Spark30

不按顺序传参:带名参数,如下
f3(param2=100,param1="Scala")
结果:Scala100

变长参数函数
def sum(numbers : Int*)={var result=0;for(element <- number) result+=element;result}
sum(1,2,3,4,5,6,7,8,9,10)
值为55

sum(1 to 100:_*) 值为5050,:_*表示将里面的每个元素提取出来,再相加
没有返回值的函数叫做过程。


八:lazy:如果一个变量声明为lazy,表示这个变量只有在第一次使用时,才会发生计算,比如说打开文件,打开数据库,操作网络,如果将变量声明为lazy,特别有用。

九:异常
try{

}catch{

}finally{
println("finally")
}

//注意:与Java中的异常稍微不一样。


十:集合操作
创建不可变数组:val arr = new Array[Int](5) //创建了一个不可变的数组,大小为5,官方说法:val表示arr本身的对象不可修改,但对象的内容是可以修改的
访问元素:arr(3) //访问第4个元素。
修改元素的值:arr(2)= 8


创建不可变数组时并赋值:val arr1 = Array("Scala","Spark")
其实它内部用的是apply: val arr1 = Array.apply("Scala","Spark") // apply就是内部工厂方法构造器


创建可变数组:可增加或删减元素
一:导包 import scala.collection.mutable.ArrayBuffer
二:val arrBuffer = ArrayBuffer[Int]()
追加元素:arrBuffer +=10;
arrBuffer +=(11,1,3,4,5) //那么这个可变数组就有5个元素
arrBuffer ++=(1,2,3,4) //在现有的arrBuffer的5个元素的后面追加1,2,3,4 四个元素

删减元素:
arrBuffer.trimEnd(3) //截断arrBuffer后面的3个元素

固定位置加元素:arrBuffer.insert(5,100),第5个元素增加100这个元素,那么后面的元素会往后移
固定位置删元素:arrBuffer.remove(5),删除第5个位置的元素
arrBuffer.remove(5,3),第5个位置开始删除3个元素,包括5的位置

for循环遍历数组
for(element <- arrBuffer)
{
println(element)
}
数组求和:arrBuffer.sum
数组求最大值:arrBuffer.max
数组排序:scala.util.Sorting.quickSort(arrBuffer)

Map
定义不可变的Map val persons = Map("Spark" ->6,"Hadoop" -> 11)
访问key为Hadoop的Map里面的值:persons("Hadoop")

定义可变的Map
val persons = scale.collection.mutable.Map("Spark" ->6,"Hadoop" -> 11)
加元素:
persons=+("Flink" -> 5)
减元素:
persons-="Flink"

Map中的if()else()操作的变型
在Spark中写法是:persons.getOrElse("Spark",1000) //如果persons这个Map中包含有Spark,取出它的值,如果没有,值就是1000。

for循环访问persons里面的Key和value
for((key,value)<- persons)
println(key+":"+value)
值:Hadoop:11
Spark:6

创建可排序的Map:会对Map的key进行排序
val persons = scale.collection.immutable.SortedMap("Spark" ->6,"Hadoop" -> 11)

tuple:它可以存放很多的不同类型的数据
val tuple=("Spark",6,99.0)
访问:tuple._1 结果String=Spark
注:它的访问下标是从1开始的,跟数组不一样。

开发环境:

  Ubuntu 14.x

  Scala 2.10.4 

  Java 1.8

移除一个数组中第一个负数以后的负数

实现方式一:

DT大数据梦工厂大数据门徒3000第一作业答案(包含普通算法实现和高效实现)      

上述第一种实现方式由于在发现第一个负数之后的每一个负数会立即进行移除,性能较差,多次移动数组

实现方式二:

DT大数据梦工厂大数据门徒3000第一作业答案(包含普通算法实现和高效实现)

上述的方式是首先记录所有不需要移除的元素的索引,最后一次性移除所有需要移除的元素,性能相对较高

原文地址:https://www.cnblogs.com/supersom/p/5094666.html