一、上次课回顾
https://blog.csdn.net/zhikanjiani/article/details/98738943
源数据:raw
元数据:描述数据的数据,描述Hive中数据的数据.
测试删除Version表,如果会自动创建的version的话修改Hive-site.xml即可
Cpu决定并行度,Memory决定空间是否够存储。
二、变量var val
概述:var val都是修饰变量的。
val修饰的是一个值。
eg:我们定义一个值为name,name是一个名字,name的类型是string,name的值是17。
val name:String = "17"
name:String = 17 名字 value:17
var修饰的是一个变量
scala> var money:Int = 10000;
money:Int = 10000;
工资翻了一番变成2万,修改工资。
scala> money = 20000;
money:Int = 20000;
操作:修改 “17” 的名字为"dashu"
scala> name=“dashu”
:12: error: reassignment to val
name=“dashu”
^
发现无法修改,报错:reassignment to val
re assign ment :再一次分配(重新给val赋值失败,因为val是不可变的)
在Scala中定义一个名称的东西,所有的都是val、var.
scala 中的数据类型是可以自动推导的。
scala> val name = "john"
name:String = john
scala> val age = 3
age:Int = 3
Scala中的数据类型:Int、Short 、Long、FLoat、Doube、Boolean、Byte、Char、
scala> val money = 2504287548l
money:Long = 2504287548l
var类型:
scala> var a:Int = 100
a:Int = 100
scala> val b:Float = 1.1f
b: Float = 1.1
类型不匹配:
scala> var a:Int = 100f
:11: error: type mismatch;
found : Float(100.0)
required: Int
var a:Int = 100f
**
类型转换
asInstanceOf VS isInstanceOf :
整型转换成double型:
val a = 10.asInstanceOf[Double]
a:Double = 10.0
类型判断:
val b = 10.inIstanceOf[Int]
b: Int = 10
三、 函数、方法
3.1 Scala中函数的定义
def max(x:Int,y:Int):Int = { // :Int返回值是Int类型
if(x>y){
x //返回值
}else{
y //返回值
}
}
解释:
1、def:定义函数的关键字
2、max:函数的名称,比较最大值
3、(x:Int,y:Int):叫做函数的入参,可能没有可能有多个。每一个参数的定义:(参数名称:参数类型)。两个括号之间 {} 的叫函数体。
4、函数体的最后一行表示返回值;X 和Y就是返回值。
5、max那一行,:Int 指的是返回值类型。
package com.ruozedata.bigdata.scala01.com.ruozedata.bigdatascala02
object scala02 {
def main(args: Array[String]): Unit = {
print(sum(2,4)) 此处进行打印
}
如下进行定义:
def sum(x: Int, y: Int): Int = {
x + y
}
}
Int类型+Int类型一定是一个Int类型,不可能变成string类型,所以输出值的Int类型可以不写。
简写:def sum(x:Int,y:Int):Int = x + y
注意在idea中,def sum(x:Int,y:Int){},在Int后输入大括号,idea会自动跳出unit,注意unit类型返回的是空值。
请注意细微差别:
package scala02
object Function {
def main(args: Array[String]): Unit = {
println(sum(3,7))
}
def sum(x:Int,y:Int):Unit ={
x + y
}
}
此时的输出是:()
3.2 函数调用
package com.ruozedata.bigdata.scala01.com.ruozedata.bigdatascala02
object FunctionApp {
def main(args: Array[String]): Unit = {
sayHello() 此处为函数的调用
}
如下是函数定义
def sayHello(): Unit ={
println("若泽数据欢迎您")
}
}
进行变更:打印出的加一个人
package com.ruozedata.bigdata.scala01.com.ruozedata.bigdatascala02
object FunctionApp {
def main(args: Array[String]): Unit = {
sayWord(name = "john") 此处为函数的调用
}
如下是函数定义
def sayWord(name:String): Unit ={
println("若泽数据欢迎您"+name)
}
}
输出信息:
若泽数据欢迎你....john
3.3 函数循环表达式
函数中to、until、range的区别:
求1到10的和:
1、在Scala下1 to 20,调用了一个scala.collection.immutable.Range.Inclusive的方法
inclusive包含1 to 20是一个左闭右闭的区间。
scala> 1 to 10
res4: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
2、Range是一个左闭右开区间
scala> Range(1,10)
res12: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
3、Range方法按步长递增:
scala> Range(1,20,5)
res14: scala.collection.immutable.Range = Range(1, 6, 11, 16)
- Range方法按步长递减,顾头不顾尾
scala> Range(10,1,-1)
res16: scala.collection.immutable.Range = Range(10, 9, 8, 7, 6, 5, 4, 3, 2)
1 to 10 左闭右闭 ==》1.to(10)
1 until 10 左闭右开 ==》1.until(10)
Range(1,10) 左闭右开 ==》1.until(10)
res5: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
Range(1,10,0) java.lang.IllegalArgumentException: step cannot be 0 报错提示步长不能为0
有能力的小伙伴可以直接去到Range.scala源码中去查看信息:
class Range(val start: Int, val end: Int, val step: Int)
如下源码中写明:step ==0 , 就抛出异常.
def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = {
if (step == 0)
throw new IllegalArgumentException("step cannot be 0.")
需求:输出1到20以内能被2整除的数字。
for (i <- 1 to 20 if i%2 == 0)
print(i)
打印出结果:2468101214161820
上面是to的输出,我们来看until的输出
for (i <- 1 to 20 if i%2 == 0)
print(i)
打印出结果:24681012141618
源码面前了无秘密:
to的底层调用until:
- def to(end: Int): Range.Inclusive = Range.inclusive(self, end)
- def until(end: Int): Range = Range(self, end)
四、面向对象编程
class来定义类:人、猫、狗
类中包含属性、方法; 属性var、val;方法是def
Class是要new出来才能使用的。
class People{
val name = “” //此处的name肯定是一个字符串类型
val city = “”
定义人的方法:
def sleep() = { 无参
name + “ZZZZZZZ…”
}
def py(pyName:String):Unit = { 有参,无返回值,跟谁进行PY交易
println(name+“正在和”+pyname+“XXX”)
}
package com.ruozedata.bigdata.scala01.com.ruozedata.bigdatascala02.scalatest
object demo {
def main(args: Array[String]): Unit = {
val people = new People //先new一个人,可以理解为引用,所有的操作都是基于people这个人来操作
people.name = "john"
println(people.sleep())
people.py("大树")
}
class People {
var name = "" //name是一个字符串类型
val city = ""
def sleep() = {
name + "~~~ZZZZZ....."
}
def py(pyName:String) ={
println(name + "正在和" + pyName + "XXX")
}
}
输出信息:
john~~~ZZZZZ.....
john正在和dashuXXX
此时出现报错:
- reassignment to val 如果要声明其值可变的变量,可以用var
注意:
- class是要new才能使用,People这个类;new一个人,val people = new People.
class来修饰类,People是类名,类里面可以跟上属性与方法,在跟上属性的时候可以使用占位符,但需写明占位符的字符类型
在scala中还能直接使用占位符:
class People {
var name = _ //name是一个字符串类型
val city = ""
} _指的是unbound placeholder parameter:未绑定占位符参数
- var 属性 = _ 表示的是占位符
- 需要明确给出属性的字符类型:var name:String = _
五、Scala实际编程
第一次编程:
package com.ruozedata.bigdata
object SparkConfAPP {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf
sparkConf.setMaster("SparkConfApp")
sparkConf.setAppName("yarn")
sparkConf.printInfo() //通过调用把我们设置进去的东西取出来
}
}
class SparkConf{
var master:String = _
var appName:String = _
def setMaster(master:String): Unit ={
this.master = master
}
def setAppName(name:String)={
this.appName = name
}
def printInfo(): Unit ={
println(this.master + " " + this.appName)
}
}
输出结果(SparkConfApp yarn)
第二次编程(在1的基础上做修改):转换成通用形态
package com.ruozedata.bigdata.scala01.com.ruozedata.bigdatascala02.scalatest
import java.util.concurrent.ConcurrentHashMap
object SparkConf {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf
sparkConf.setAppName("SparkConfApp").setMaster("yarn") //(1)怎么做到连起来写
sparkConf.printInfo()
}
}
class SparkConf{
var master:String = _
var appName:String = _
//(4)放一个支持并发的东西
var setting = new ConcurrentHashMap[String,String]()
def setMaster(master:String): SparkConf = { //(2)返回当前对象SparkConf
set("spark.master",master) //(5)
}
def setAppName(name:String): SparkConf = {
set("spark.app.name",name)
}
//在1中我们是1个1个放进去的,那比如一批是100个怎么办呢
//key、value的数据结构==>map,每调用一次放入一个(key,value)
def set(key:String,value:String):SparkConf = {
setting.put(key,value)
this
}
def printInfo(): Unit ={
//println(this.master + ":" + this.appName) //取值的时候也要做修改了,修改如下:
val appName = setting.get("spark.master")
val master = setting.get("spark.app.name")
println(appName + ":" + master)
}
}
输出:yarn:SparkConfApp
扩展的语法
Private加了之后只能自己使用:
private [this] def set(key:String,value:String):SparkConf = {
加了private this 后,外部的set方法就用不了报错:symbol set is inaccessible from this place;
在pom.xml中添加spark.verison的依赖
<properties>
<spark.version>2.4.2</spark.version>
</properties>
---------------------------------------------------
<!--添加Spark Core依赖-->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
这样做了之后可以查看SparkConf的源码
查看SparkConf.scala源码中看看标准的SparkConf是怎么写的??
1、 private val settings = new ConcurrentHashMap[String, String]()
2、def setMaster(master: String): SparkConf = {
set("spark.master", master)
}
/** Set a name for your application. Shown in the Spark web UI. */
def setAppName(name: String): SparkConf = {
set("spark.app.name", name)
}
3、 /** Set a configuration variable. */
def set(key: String, value: String): SparkConf = {
set(key, value, false)
}
private[spark] def set(key: String, value: String, silent: Boolean): SparkConf = {
if (key == null) {
throw new NullPointerException("null key")
}
六、主构造器和附属构造器
主构造器:
package com.ruozedata.bigdata.scala02
object ConstructorDemo {
def main(args:Array[String]):Unit{
val person = new Person
println(person.name + ":" + person.city)
}
//主构造器,class修饰的时候,class方法底层就有一个主构造器
class Person(var name:String,var city:String){
println("person here")
println("person leave")
}
}
输出信息:
person enter....
person leave......
john生活在苏州
附属构造器:
package com.ruozedata.bigdata.scala01.com.ruozedata.bigdatascala02.scalatest
object ConstructorDemo {
def main(args: Array[String]): Unit = {
val person = new Person("john","苏州")
println(person.name+ ":" + person.city)
val person1 = new Person("sail","苏州",25)
println(person1.name + ":" + person1.city + ":" + person1.age)
}
//主构造器,跟在class后面的
class Person(var name:String,var city:String){
var age:Int = _
//附属构造器 第一行必须要调用主构造器或者其他附属构造器,使用this关键字
def this(name:String,city:String,age:Int){
this(name,city)
this.age = age
}
}
输出打印值:
john生活在苏州
sail生活在苏州年龄是25