本文档由博主参考慕课网学习Scala进击大数据Spark生态圈整理
https://zh.wikipedia.org/wiki/Scala
面向对象、函数式编程、基于Java虚拟机
https://www.scala-lang.org/
Scala combines object-oriented and functional programming in one concise, high-level language. Scala’s static types help avoid bugs in complex applications, and its JVM and JavaScript runtimes let you build high-performance systems with easy access to huge ecosystems of libraries.
Spark、Kafka、Flink生态圈
Java 1.8、Scala 2.11.8
Scala使用入门
不强求每行以;结尾
scalac、scala
object HelloWorld {
def main(args: Array[String]) {
println("hello world")
}
}
val: 类似于java中的final (值)、var (变量)
Scala基本数据类型
Byte/Char、Short/Int/Long/Float/Double、Boolean
val a = 10.asInstanceOf[Double]
val b = 10.isInstanceOf[Int]
lazy在Scala中的使用
lazy val a = 1
Scala常见的IDE
IDEA整合Maven构建Scala应用
函数的定义和使用
def max(x: Int, y: Int): Int = {
if (x > y)
x
else
y
}
方法体最后一行作为返回值不需要return
没有入参的函数在调用时括号是可以省略的
默认参数的使用
命名参数的使用
def speed(distance: Double, time: Double): Double = {
distanec/time
}
speed(100, 10)
speed(distance=100, time=10)
speed(time=10, distance=100)
可变参数的使用
def sum(numbers: Int*) = {
var res = 0
for (number <- numbers) {
res += number
}
}
条件表达式
val a = if (x > 0) true else false
循环表达式
1 to 10 // 左闭右闭
1.to(10)
Range(1, 10) // 左闭右开
1 until 10 // 左闭右开
1.until(10)
for (item <- arr) {
println(item)
}
arr.foreach(item ==> println(item))
x = 0
while (x > 10) {
println(x)
x += 1
}
面向对象概述
类的定义和使用
占位符_
var a1: Int = _ // 0
var a2: String = _ // ""
var a3: Double = _ // 0.0
val b: Int = _ // 值不能使用占位符
主构造器和附属构造器
class Person(val name: String, val age: Int) {
println("Person constructor enter ...")
val school = "xidian"
var gender = _
println("Person constructor leave ...")
def this(name: String, age: Int, gender: String) {
this(name, age) // 附属构造器的第一行代码必须调用主构造器或者其他附属构造器
this.gender = gender
}
}
继承
class Student(name: String, age: Int, val major; String) extends Person(name, age) {
println("Person Student constructor leave ...")
println("Person Student constructor leave ...")
}
重写
override val school = "beihang"
override def toString: String = "override def toString"
使用override对父类的属性和方法进行重写
抽象类
类的一个或多个方法没有完整实现 (只有定义没有实现)
abstract class Person {
val name: String
val age: Int
def speak
}
class Student extends Person{
override def speak: Unit {
println("speak")
}
override val name: String = _
override val age: Int = _
}
伴生类和伴生对象
若class和object同名 则称class为object的伴生类 object为class的伴生对象
apply方法
object ApplyApp {
def main(args: Array[String]): Unit {
for (i <- 1 to 10) {
ApplyTest.incr
}
println(ApplyTest.count) // 10 说明object本身就是一个单例对象
val a = ApplyTest() // 类名(): 调用的是Object中的apply方法
val b = new ApplyTest()
println(b)
b() // 对象(): 调用的是Class的Apply
}
}
class ApplyTest {
def apply() {
println("Class ApplyTest apply")
}
}
object ApplyTest {
println("Object ApplyTest enter ...")
var count = 0
def incr = {
count += 1
}
// 最佳实践: 在object的apply方法中new class
def apply() {
println("Object ApplyTest apply")
new ApplyTest
}
println("Object ApplyTest leave ...")
}
case class
def main(args: Array[String]): Unit {
println(Dog("wangcai").name) // wangcai
}
// case class不用new
// 通常用在模式匹配里
case class Dog(name: String)
trait
定长数组
object ArrayApp extends App {
println("ok")
val a = new Array[String](5)
// a.length
// a(1) = "hello"
val b = Array("hadoop", "spark", "storm") // object中的apply方法
b(1) = "scala" // val b指的是数组的指针不变
val c = Array(1, 2, 3, 4, 5, 6)
// c.sum/c.min/c.max
// c.mkString("")
// c.mkString(",")
// c.mkString("<", ",", ">")
}
变长数组
object ArrayApp extends App {
val a = scala.collection.mutable.ArrayBuffer[Int]()
a += 1 // 1
a += 2 // 1 2
a += (3, 4, 5) // 1 2 3 4 5
a ++= Array(6, 7, 8) // 1 2 3 4 5 6 7 8
a.insert(0, 0) // 0 1 2 3 4 5 6 7 8
a.remove(0, 3) // 3 4 5 6 7 8
a.trimStart(2) // 5 6 7 8
a.trimEnd(2) // 5 6
a.toArray // 转成定长Array
}
List
Nil: scala.collection.immutable.Nil.type = List()
val l = List(1, 2, 3, 4, 5)
l.head // 1
l.tail // List(2, 3, 4, 5)
val l2 = 1::Nil // 一头一尾 List(1)
val l3 = scala.collection.mutable.ListBuffer[Int]()
l3 ++= List(1, 2, 3, 4, 5, 6)
l3 -= 1 // 2 3 4 5 6
l3 --= List(6, 7) // 2 3 4 5
l3.toList // 转成定长List
l3.toArray
l3.tail.head // 3
def sum(nums: Int*):Int {
if (nums.lenght == 0) {
0
} else {
nums.head += sum(num.tail:_*) // 将Seq转为可变参数
}
}
Set
val s = Set(1, 1, 2, 3) // Set(1, 2, 3)
基本数据类型模式匹配
import scala.util.Random
object MatchApp extends App {
val age = 18
val names = Array("A", "B", "C")
val name = names(Random.nextInt(names.length))
name match {
case "A" => println("a")
case "B" => println("b")
case "C" => println("c")
case _ if (age==18) => println("no idea (conditional)")
case _ => println("no idea")
}
}
Array模式匹配
def greeting(array:Array[String]): Unit {
array match {
case Array("zisheng") => println("hi zisheng")
case Array(x, y) => println("hi " + x + " and " + y)
case Array("zisheng", _*) => println("hi zisheng and everybody")
case _ => println("hi everybody")
}
}
List模式匹配
def greeting(list:List[String]): Unit {
list match {
case "zisheng"::Nil => println("hi zisheng")
case x::y::Nil => println("hi " + x + " and " + y)
case "zisheng"::tail => println("hi zisheng and everybody")
case _ => println("hi everybody")
}
}
类型模式匹配
def matchType(obj:Any): Unit {
obj match {
case i:Int => println("Int")
case s:String => println("String")
case m:Map[_, _] => println("Map")
case _ => println("Other types")
}
}
Scala异常处理
try {
val a = 10/0
} catch {
case e:ArithmeticException => println("divided by zero")
case e:Exception => println(e.getMessage)
} finally {
// 释放资源文件 一定能执行
}
case class模式匹配
class Person
case class CEO(name:String) extends Person
case class Employee(name:String) extends Person
case class Others(name:String) extends Person
def caseClassMatchApp(person:Person):Unit {
person match {
case CEO(name) => println("CEO")
case Employee(name) => println("Employee")
case _ => println("Others")
}
}
字符串高级操作
匿名函数
val incByOne = (x:Int) => x + 1
def add = (x:Int, y:Int) => x + y
curry函数
def sum(x:Int)(y:Int) = x + y
高级函数
val l = List(1, 2, 3, 4, 5, 6, 7)
// map: 逐个操作集合中的每个元素
l.map((x:Int) => x + 1)
l.map((x) => x + 1)
l.map(x => x + 1)
l.map(_ + 1).foreach(println)
//filter
l.filter(_ > 4)
// take: 取集合中的前几个元素
l.take(2)
//reduce
l.reduce(_ + _)
//flatten
List l2 = List(List(1, 2), List(3, 4))
l2.flatten // List(1, 2, 3, 4)
l2.flatMap(_.map(_*2)) // List(2, 4, 6, 8)
偏函数
为已存在的第三方类添加一个新的方法
import java.io.File
object ImplicitApp extends App {
// 定义隐式转换函数即可
implicit def man2Superman(man:Man): SuperMan = new SuperMan(man.name)
val man = new Man("zisheng")
man.fly()
implicit def file2RichFile(file:File): RichFile = new RichFile(file)
val file =. new File("../data/hello.txt")
val txt = file.read // File本身没有read()方法
println(txt) // 打印txt文件中的内容
}
class Man(val name: String): Unit {
def eat() = {
println(s"Man $name eat")
}
}
class SuperMan(val name: String): Unit {
def fly() = {
println(s"Superman $name fly")
}
}
class RichFile(val file: File) {
def read() = {
scala.io.Source.fromFile(file.getPath).mkString
}
}
隐式转换切面封装
隐式参数
def testParam(implicit name:String): Unit = {
println(name)
}
// testParam("zisheng")
implicit val name = "zisheng"
testParam // 运行成功
隐式类
object ImplicitClassApp extends App {
implicit class Calculator(x:Int) {
def addTwo(y:Int) = x + y
}
println(1.addTwo(2)) // 3
}
Scala读取文件及网络数据
import scala.io.Source
object FileApp extends App {
val file = Source.fromFile("../data/hello.txt")
def readFileLine(): Unit = {
for (line <- file.getLines()) {
println(line)
}
}
readFileLine
def reafFileChar(): Unit = {
for (ele <- file) {
println(ele)
}
}
reafFileChar
def readNet(): Unit = {
val net = Source.fromURL("http://www.baidu.com")
for (line <- net.getLines()) {
println(line)
}
}
}
Scala读取MySQL数据库
Scala读取XML文件
import scala.xml.XML