spark源码:https://github.com/apache/spark/archive/v2.2.2.zip

主构造器、附属构造器

主构造器用clclass定义,附属构造器用def定义名称为this(),
在附属构造器的第一行必须调用主构造器和其他附属构造器。

/**
 * scala 中的构造器
 */
// 主构造器
class ContructTest(name: String, age: Int) {
  val famila: String = "hello"
  val height: Int = 10

  def this(name: String) {
    this(name, 12)
  }

  // 辅助构造器第一行必须调用主构造器或者其他附属构造器
  def this(name: String, age: Int, salary: Int) {
    this(name)
  }
  
  def eat(): String = {
    " eat breakfast"
  }
}

抽象类和抽象方法

在抽象类中定义的方法如果没有方法体,那么在子类中必须重写该方法

abstract class Animal {
  val color: String
  def eat()
  def run()={
    println("hello")
  }
}

class Bord extends Animal {
  override val color: String = ""
  override def eat(): Unit = {
    println("eat")
  }
}

半生类和半生对象,当class定义的类名和object定义的名称相同的时候,class定义的叫做objec 对象的伴生类,object定义的叫做class的陪伴生对象。
一般在object里面定义一个apply方法,该方法通常的作用是new 一个类对象。如何判断是class的apply还是object的apply方法?
class的对象在spark的源码中调用apply方法的时候对象都是小写的
object一般都是大写的,用大写的object名称调用apply方法,即大写开头调object 小写开头调class

class Student(name: String, age: Int) {
  val money = 200

  def write() = {
    println("student write homework")
  }
}

object Student {
  val project: String = "math"

  def study() = {
    println("student study")
  }

  def apply(name: String, age: Int): Student = new Student(name, age)
}

Scala 中的样例类

样例类 用case class 来修定义样例类,可以当做静态来理解,用Dog()这种方式使用
与object 不同的是object 调用的时候直接是名称Dog.xxx 而caseclass则是Dog().xxx
特点是不用new可以直接使用,并且在spark sql中使用的比较多

object CaseClassApp {
  def main(args: Array[String]): Unit = {
    Dog("Tom").eat()
    println(Cat().age)
    Cat().eat()
  }
}
case class Cat() {
  val age: Int = 39
  def eat() = {
    println("Cat  eat fish")
  }
}

case class Dog(name: String) {
  val aa = "hh"
  def eat(): Unit = {
    println(name + "  eat chicken")
  }
}

Scala 中的Trait

实现Trait和abstract的时候都用extends 当有多个的时候第一个用extends,后面的用with

object TraitApp {
  def main(args: Array[String]): Unit = {
    val controller = new AnimalController()
    controller.eat()
    controller.run()
    controller.serviec()
  }
}
class AnimalController extends Dog with AnimalService with Animal {
  override def run(): Unit = {
    println("run")
  }
  override def serviec(): Unit = {
    println("service")
  }
  override def eat(): Unit = {
    println("eat")
  }
}
trait Animal {
  def eat()
}
trait AnimalService {
  def serviec()
}
abstract class Dog() {
  def run()
}

scala 中的数组Array

第一种方式定义数组 
val array = new Array[Int](10) 
for (arr <- array) {
  println(arr)
}

第二种方式定义数组 
val arr1 = Array("hello","spark","hive","hbase")
for (arr <-arr1){
  println(arr)
}
// 变长数组定义
    val arrbuff = ArrayBuffer[String]()
    // 添加元素
    arrbuff.append("hello")
    arrbuff.append("spark")
    arrbuff.append("scala")

    // 获取元素
    println(arrbuff(0))
    for (arr <- arrbuff) {
      println(arr)
    }
    // 修改元素
    arrbuff(0) = "hadoop"

    // 删除元素
    arrbuff.remove(0)
    // 获取长度
    arrbuff.length

Scala 中的变长数组

变长数组定义时需声明泛型

val arr2 = ArrayBuffer[Int]() 

变长数组的分析 
1) ArrayBuffer 是变长数组,类似 java 的 ArrayList 
2) val arr2 = ArrayBuffer[Int]() 也是使用的 apply 方法构建对象 
3) def append(elems: A*) { appendAll(elems) } 接收的是可变参数. 
4) 每append一次,arr在底层会重新分配空间,进行扩容,arr2的内存地址会发生变化,也就成为新的ArrayBuffer 

定长数组与变长数组的转换 
 
1) arr1.toBuffer  //定长数组转可变数组 
2) arr2.toArray  //可变数组转定长数组 

Scala 中的List

Scala 中的 List 和 Java List 不一样,在 Java 中 List 是一个接口,真正存放数据是 ArrayList,而 Scala 的 List
可以直接存放数据,就是一个 object,默认情况下 Scala 的 List 是不可变的,List 属于序列 Seq。

创建List val list1 = List(1, 2, 3)

  1. List 默认为不可变的集合
  2. List 在 scala 包对象声明的,因此不需要引入其它包也可以使用
  3. val List = scala.collection.immutable.List
  4. List 中可以放任何数据类型,比如 arr1 的类型为 List[Any]
  5. 如果希望得到一个空列表,可以使用 Nil 对象, 在 scala 包对象声明的,因此不需要引入其它包也可以使用

向列表中增加元素, 会返回新的列表/集合对象。注意:Scala 中 List 元素的追加形式非常独特,和 Java 不一样。

val list1 = List(1, 2, 3)
val list3 = List("hello|Spark", "word|Wall", "New|Year")

// + 进行的是字符串的拼接
val list4 = list3 + "hadoop"
//(hello|Spark, word,Wall, New|Year)hadoop

// +: 是在list的头部进行的拼接
val list5 = list3 +:("hadoop")
// List(hadoop, hello|Spark, word,Wall, New|Year)

//    val list6 = "hadoop" :+ list3
// Vector(h, a, d, o, o, p, List(hello|Spark, word,Wall, New|Year))

// :: 是将前面的List作为一个整体拼接到后面的List上面
val list7 = list1 :: list3
// List(List(1, 2, 3), hello|Spark, word|Wall, New|Year)

// zip() 是将两个List中的元素每个元素对应位置形成一个键值对
val list8 = list1.zip(list3)
// List((1,hello|Spark), (2,word,Wall), (3,New|Year))

// ::: 是将两个List中的元素进行拼接形成一个新的List
val list9 = list1.:::(List("Flink", "Flink2"))
// LList(Flink, Flink2, 1, 2, 3)

// flatMap是将一个值映射成为多个值
val list10 = list3.flatMap(x => x.split(","))
// List(hello, Spark, word, Wall, New, Year)

// ++ 是将后面List中的每一项拼接到前面List中
val list11 = list3.++(List("Shell", "Kafka"))
// List(hello|Spark, word,Wall, New|Year, Shell, Kafka)

// 对List中的每一个值进行处理,返回处理后的结果
val list12 = list1.map(x => x + 1)
// List(2, 3, 4)

// 对List中的每一个值作用上传入的函数
list1.foreach(println(_))

// List 内容的反转
val list14 = list1.reverse
// List(3, 2, 1)

Scala 中的ListBuffer

可变的List ==> ListBuffer

// ListBuffer 的创建
val buffer = ListBuffer[String]()
// 添加单个元素
buffer.append("Hadoop")
buffer.append("HDFS")

// 在指定位置添加元素
buffer.insert(0,"Shell")

// 在指定位置添加一个List
buffer.insertAll(0,List("Kafka","Hive"))

// 删除指定位置的元素
buffer.remove(0)

// 更新指定位置的元素
buffer.update(0,"HIVE")

// 获取buffer的大小
println(buffer.length)
println(buffer.size)

// 获取buffer的头部
println(buffer.head)

// 获取buffer的尾部
println(buffer.tail)

// 清空buffer
buffer.clear()
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐