文章目录

  • 1.修饰变量用val、var
  • 2.Scala里的数据类型是可以自动推导的
  • 3.Scala数据类型
  • 4.函数(方法)
  • 3.循环表达式
  • 4.面向对象
  • 类 -----针对sparkconf解析
  • 构造方法(主构造器和附属构造器)


1.修饰变量用val、var

在Scala里面,定义一个名称的东西只需要这两个就够了,不像Java等语言有很多修饰符:val var
val修饰的是不可变的
var修饰的是可变的

val name:String = “zhangsan”
定义了一个变量name,它的类型为String,它的值是zhangsan,这个变量的值不可改变
如果用var修饰,就可以改变

scala> val name:String ="zhangsan"
name: String = zhangsan

scala> name ="lisi"
<console>:12: error: reassignment to val
       name ="lisi"
            ^
scala> var city:String ="shanghai"
city: String = shanghai

scala> city ="beijing"
city: String = beijing
2.Scala里的数据类型是可以自动推导的

val 名称 = 值 只要=号后面有值,就不用写类型了,Scala中,它会自动从后面往前推导

scala> val name = "wangwu"
name: String = wangwu

scala> val age = 10
age: Int = 10

scala> var money = 111111111111
<console>:1: error: integer number too large
       var money = 111111111111
                   ^
#后面需要加个L
scala> var money = 2222222222222L
money: Long = 2222222222222

scala> val a:Float = 1.2
<console>:11: error: type mismatch;
 found   : Double(1.2)
 required: Float
       val a:Float = 1.2
                     ^
#上面这种情况需要加个f/F
scala> val a:Float = 1.2f
a: Float = 1.2
3.Scala数据类型

Scala中有很多数据类型,比如
Byte Char
Short Int Long Float Double
Boolean

数据类型转换:
asInstanceOf 类型转换
isInstanceOf 判断类型

#将整型10 转换为Double型
scala> val aaa = 10.asInstanceOf[Double]
aaa: Double = 10.0
#判断aaa是否为Int类型
scala> aaa.isInstanceOf[Int]
res1: Boolean = false
#判断10.1是不是Int类型
scala> 10.1.isInstanceOf[Int]
res2: Boolean = false
4.函数(方法)

SparkConf 配置远程服务器_SparkConf 配置远程服务器

package com.ruozedata.bigdata.scala02

object FunctionApp {
  def main(args: Array[String]): Unit = {
    println(sum(12, 23))
    sayHello           //函数没有入参,括号可以省略    所以也可以这样写sayHello
    sayWorld("world")      //这个括号不能省略
  }

  def sum(x: Int, y: Int):Int = {
    x + y
  }
  def sayHello(): Unit ={
    println("welcome to China")
  }
  def sayWorld(name:String): Unit ={
    println("Hello " + name)
  }
}

当方法体只有一行时,可以直接这样写:

def sum(x: Int, y: Int)= x + y

写代码的时候,还是按照最上面那个写,老老实实的写,按照正常来写,除非你很牛逼。

注意函数上面有Unit这个时,是没有返回值的。

3.循环表达式

1到10
1 to 10 : [] 这个是左闭右闭 等价于 1.to(10) 产出Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Range(1,10) : [) 左闭右开
Range(1,10,2) 2是步长
1 until 10 等价于Range(1,10) 等价于 1.until(10)

看源代码,to until 底层调用的都是Range 只是Inclusive 或者否罢了

scala> 1 to 10
res5: scala.collection.immutable.Range.Inclusive = Range 1 to 10
scala> Range(1,10)
res6: scala.collection.immutable.Range = Range 1 until 10
scala> Range(1,10,2)
res7: scala.collection.immutable.Range = inexact Range 1 until 10 by 2
scala> Range(10,1,-1)
res8: scala.collection.immutable.Range = Range 10 until 1 by -1
scala> 1 until 10
res9: scala.collection.immutable.Range = Range 1 until 10

使用:

#把1到10的数字 分别赋值给i   然后里面循环打印i
    for(i <- 1 to 10){
      println(i)
    }

一个if语句:

val x = 10
    if(x>0){
      true
    }else{
      false
    }
#可以简化为:
  val x = 10
  if(x>0) true else false

打印1到10之间的偶数

for(i <- 1 to 10    if i%2==0){
      println(i)
    }
4.面向对象
类 -----针对sparkconf解析

class 来定义类
类中包含了属性和方法。
class是要new出来才能进行属性方法的调用。

val 属性=_
这个下划线 表示占位符 先占个坑,先不管如何使用它,先占个坑再说
var name = _ 这样是错误的,因为先占个坑的话,需要指定一个数据类型
var name:String = _ 这样是对的

#有默认值
scala> var d:Double = _
d: Double = 0.0

scala> var d:String =_
d: String = null

举例:

object SparkConfApp {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf
    sparkConf.setAppName("SparkConfApp")
    sparkConf.setMaster("yarn")
    sparkConf.printInfo()
  }
}
class SparkConf{
  var master:String = _
  var appName:String = _

  def setMaster(master:String): Unit ={
    this.master = master
  }
  def setAppName(name:String): Unit ={
    this.appName = name
  }
  def printInfo(): Unit ={
    println(this.appName + ":" + this.master)
  }
}

由上面代码衍生出升级版:

package com.ruozedata.bigdata.scala02

import java.util.concurrent.ConcurrentHashMap

object SparkConfApp {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf
    sparkConf.setAppName("SparkConfApp").setMaster("yarn")   //链式编程

    sparkConf.printInfo()
  }
}

class SparkConf{
  var master:String = _
  var appName:String = _

  //在这里定义一个setting,里面可以放好多东西,先不用管它什么意思
  //可以先把两个值放里面,然后用的时候再取出来
  var setting = new ConcurrentHashMap[String,String]()

  //这个方法的数据结果是key,value结构,它的底层肯定是个Map
  //调用上面的setting,来设置key,value
  //后面调用一下set方法,就可以设置key,value了
  //放值是用setting.put(key,value),取值是setting.get(key),放进去什么就取什么
  //就是弄一个key放进去,把这个key的值设置为value值,当取的时候,直接用key去获取这个值就行了
  //private表示私有的,只能在自己的类里面使用
  private[this] def set(key:String,value:String):SparkConf = {
    setting.put(key,value)
    this
  }

  //调用set方法,设置master,master的key是spark.master,master的value是你传进来的值
  def setMaster(master:String): SparkConf ={   //返回值是SparkConf ,这样才能实现链式编程
    set("spark.master",master)
  }

  //调用set方法,设置name
  def setAppName(name:String): SparkConf ={
    set("spark.app.name",name)
  }

  def printInfo(): Unit ={
    //在这里就可以取值了,用"spark.app.name"这个key,可以取到对应的值了
    val appName = setting.get("spark.app.name")
    val master = setting.get("spark.master")
    println(appName + ":" + master)
  }
}

可以看一下orge.apache.spark.SparkConf里面的源码,和上面一样
需要在pom.xml文件里加入下面:

<properties>
    <spark.version>2.4.0</spark.version>
  </properties>
  
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-core_2.11</artifactId>
      <version>${spark.version}</version>
    </dependency>
构造方法(主构造器和附属构造器)

创建对象的时候需要借助构造方法的。
其实上面的类就是一个构造方法。
如果你这样写

class Person(val name:String,val city:String){
}

底层会自动这样处理:

class Person1(){
  val name:String =_
  val city:String =_
}

现在写一个构造方法:

object ConstrutorDemo {
  def main(args: Array[String]): Unit = {
    val person = new Person("Jerry","shanghai")
    println(person.name + " : " + person.city)
  }
}
class Person(val name:String,val city:String){
  println("person enter....")

  println("person leave....")
}

运行结果:

person enter....
person leave....
Jerry : shanghai

Process finished with exit code 0

其实在new 一个Person的时候,类里面的代码已经先执行完了。

主构造器:class + 类名 就是主构造器
跟在class后面的就是主构造器(上一节的那些类都是主构造器)
这个Person就是主构造器

class Person(val name:String,val city:String){
  println("person enter....")
  println("person leave....")
}

主构造器,附属构造器,综合代码:

object ConstrutorDemo {
  def main(args: Array[String]): Unit = {
    val person = new Person("Jerry","shanghai")  //这里面不能把age加上
    println(person.name + " : " + person.city + " : " + person.age)

    val person2 = new Person("Jerry","beijing",20)   //这里面可以加上age
    println(person2.name + " : " + person2.city + " : " + person2.age)
  }
}

class Person(val name:String,val city:String){
  println("person enter....")

  var age:Int =_

  //附属构造器 第一行必须要调用主构造器或者其他附属构造器
  //固定写法
  def this(name:String,city:String,age:Int){
    this(name,city)    //第一行必须这样写
    this.age = age    //这里的this指的是主构造器
  }
  println("person leave....")
}

运行结果:

person enter....
person leave....
Jerry : shanghai : 0
person enter....
person leave....
Jerry : beijing : 20

Process finished with exit code 0