大數據開發成長之路——Scala程序設計(一)

Scala基礎

簡介

Scala是運行在 JVM 上的多範式編程語言,同時支持面向對象面向函數編程,隨着SparkKafka這樣基於Scala的大數據框架的興起,Scala逐步成爲大數據行業編程的首選。
Scala的優勢主要是:

  • 開發大數據應用程序(Spark程序、Flink程序)
  • 表達能力強,一行代碼抵得上Java多行,開發速度快
  • 兼容Java,可以訪問龐大的Java類庫

環境

  • Scala程序運行在JVM之上,所以必須要有Java運行環境,Scala才能正確執行
  1. 安裝JDK 1.8 版本,並配置好環境變量,注意:版本一定是JDK8,雖然現在已經到了JDK13

Java SE 8就是Java8,或者jdk1.8

  1. 下載Scala SDK,並配置環境變量
  2. 編譯器仍然使用IDEA,需要安裝Scala插件

插件在官網下載,要對應你的IDEA版本
插件的安裝:【settings——plugins——Install Plugin From Disk】選擇下載的壓縮包即可!

  1. 使用IDEA新建工程,選擇scala
    在這裏插入圖片描述

語法

變量聲明

val/var 變量名稱:變量類型 = 初始值

  • val定義的是不可重新賦值的變量(值不可修改)
  • var定義的是可重新賦值的變量(值可以修改)
  • 如果變量類型不顯式聲明則會自行推斷
  • scala的語句最後不需要添加分號

惰性變量

  • scala中使用關鍵字lazy來定義惰性變量,實現延遲加載(懶加載)
  • 惰性變量只能是不可變變量,並且只有在調用時,纔會去實例化這個變量

數據類型

基礎類型 類型說明
Byte 8位帶符號整數
Short 16位帶符號整數
Int 32位帶符號整數
Long 64位帶符號整數
Char 16位無符號Unicode字符
String Char類型的序列(字符串)
Float 32位單精度浮點數
Double 64位雙精度浮點數
Boolean true或false
  • scala中所有的類型都使用大寫字母開頭
  • 類型說明:
類型 說明
Any 所有類型的父類,,它有兩個子類AnyRef與AnyVal
AnyVal 所有數值類型的父類
AnyRef 所有對象類型(引用類型)的父類
Unit 表示空,Unit是AnyVal的子類,它只有一個的實例(),它類似於Java中的void,但scala要比Java更加面向對象
Null Null是AnyRef的子類,也就是說它是所有引用類型的子類。它的實例是null, 可以將null賦值給任何對象類型
Nothing 所有類型的子類不能直接創建該類型實例,某個方法拋出異常時,返回的就是Nothing類型,因爲Nothing是所有類的子類,那麼它可以賦值爲任何類型

在這裏插入圖片描述

條件表達式

  • scala中的表達式都是有值的,可以理解爲表達式是scala中的常用單元或“數據類型”
	val x =1
    val z = if(x>1) 1 else "error"
    print(z)  // error

塊表達式

  • 塊表達式也是有值的
	val result = {
	    val x=0
	    val y = x+10
	    val z = y+"-hello"
	    val m = z+"-kaikeba"
	    "over"		// 最後的over賦給result
  	}

for循環

  • 和go語言的語法很相似
	val nums= 1 to 10
    for(i <- nums) println(i)
	// 雙重for循環
    for(i <- 1 to 3; j <- 1 to 3) println(i*10+j)
	// 乘法表
	for(i <- 1 to 9; j <- 1 to i){
	    print(i+"*"+j+"="+i*j+"\t")
	     if(i==j){
	       println()
	    }    
	}
  • 守衛:for循環中的if判斷
	for(i <- 1 to 10 if i >5) println(i)
  • 推導式:使用yield的for表達式,可以構建出一個集合
	val v = for(i <- 1 to 5) yield i * 10
    println(v)  // Vector(10, 20, 30, 40, 50)

方法

def methodName (參數名:參數類型, 參數名:參數類型) : [return type] = {
// 方法體
}

  • 參數列表的參數類型不能省略
  • 返回值類型可以省略,根據方法體的最後一行值確定
  • 在定義方法時可以給參數定義一個默認值
  • 調用方法時,可以指定參數的名稱傳值
	def add(a:Int,b:Int) = {
    	a+b
    	"value"
  	}
  	print(add(1,2))	// value
  • 如果定義遞歸方法,不能省略返回值類型
	def m1(x:Int):Int={
	    if (x==1) 1
	    else x*m1(x-1)
	}
	print(m1(10))	// 3628800
  • 變長參數:
	def add(num:Int*) = num.sum
	print(add(1,2,3,4)) // 10

函數

  • scala支持函數式編程,編寫Spark/Flink程序會大量使用到函數

val 函數變量名 = (參數名:參數類型, 參數名:參數類型…) => 函數體

  • 函數是一個對象(變量)
  • 一個函數沒有賦予一個變量,則稱爲匿名函數
  • 無需指定返回值類型
	val add = (x:Int, y:Int) => x + y
  	print(add(2,3)) 

數組

  • scala中,有兩種數組,一種是定長數組,另一種是變長數組
  • 定長數組

// 通過指定長度定義數組
val/var 變量名 = new Array[元素類型](數組長度)

// 用元素直接初始化數組
val/var 變量名 = Array(元素1, 元素2, 元素3…)

	val a = new Array[Int](10)  // 長度爲10的數組
    a(0) = 666
    print(a(0)) // 0

    val b = Array("hadoop","spark","hive") // 初始化
    print(b.length) // 3
  • 變長數組

創建變長數組,需要提前導入ArrayBuffer類:
import scala.collection.mutable.ArrayBuffer

  1. 使用+=添加元素
  2. 使用-=刪除元素
  3. 使用++=追加一個數組到變長數組
	var c = ArrayBuffer[Int](666,888)
    c += 999  // 追加
    c -= 888  // 刪除
    c ++= a   // 追加一個變長數組
    print(c)  // ArrayBuffer(666, 999, 666, 0, 0, 0, 0, 0, 0, 0, 0, 0)
  • 遍歷數組
	for(i <- a)println(i)
	for(i <- 0 to a.length -1 )println(a(i))	
	for(i <- 0 to a.length -1 )println(a(i))	// 0 until n ——生成一系列的數字,包含0,不包含n
  • 數組常見操作
  1. 求和——sum方法
  2. 求最大值——max方法
  3. 求最小值——min方法
  4. 排序——sorted方法
	array.sum
	array.max
	array.min
	array.sorted
	array.sorted.reverse

元組

  • 元組可以用來包含一組不同類型的值

val/var 元組變量名稱 = (元素1, 元素2, 元素3…)
val/var 元組變量名稱 = 元素1->元素2 // 只有兩個元素時

	val a = (1, "張三", 20, "北京市") 
	val b = 1->2 
	// 訪問元組中的元素_1、_2、_3....
	print(a._1)	// 1

Map

  • Map可以稱之爲映射。它是由鍵值對組成的集合,scala當中的Map集合與java當中的Map類似

val/var map = Map(鍵->值, 鍵->值, 鍵->值…) // 推薦,可讀性更好

  • 不可變Map:
	val map1 = Map("zhangsan"->30, "lisi"->40) 
	print(map1("zhangsan"))	// 30
	println(map1.getOrElse("wangwu", -1))	// 如果沒有key,返回-1而不是保錯
  • 可變Map
	import scala.collection.mutable.Map	// 需要導包,語法相同
	map1("zhangsan") = 50
	map3 += ("wangwu" ->35) // 添加key-value
	map3 -= "wangwu"		// 刪除key-value
	println(map3.keys)    // Set(zhangsan, wangwu)
    println(map3.keySet)  // Set(zhangsan, wangwu)
    println(map3.values)  // HashMap(50, 40)
    // 遍歷
    for((k,v) <- map3) println(k+" -> "+v)

Set

  • Set是代表沒有重複元素的集合
  • Set沒有順序
  • 不可變集合

//創建一個空的不可變集
val/var 變量名 = Set[類型]()

//給定元素來創建一個不可變集
val/var 變量名 = Set[類型](元素1, 元素2, 元素3…)

  • 可變集合

必須導入:import scala.collection.mutable.Set
創建方法和不可變集合相同

	val set = Set(1,1,2,3,4,5)
    println(set.size)
    for(i <- set) println(i)
    set += 6   		 //添加元素
    set += (6,7,8,9) // 添加多個元素
    println(set)
    set -= 1   		// 刪除一個元素
    set -= (9,10)   // 刪除多個元素
    println(set)
    set --= Set(2,3)   // 刪除一個集合
    println(set)
    set ++= Set(6,7,8) // 拼接兩個集合
    println(set)
    println(set & Set(3,6))//求2個Set集合的交集
    set.remove(8)
    println(set)

List

  • List是scala中最重要的、也是最常用的數據結構
  • 有序、可重複
  • 不可變列表:
	val/var 變量名 = List(元素1, 元素2, 元素3...)
	//使用 Nil 創建一個不可變的空列表
	val/var 變量名 = Nil
	//使用 :: 方法創建一個不可變列表
	val/var 變量名 = 元素1 :: 元素2 :: Nil
  • 可變列表

必須導入 :import scala.collection.mutable.ListBuffer

	val list4 = ListBuffer[Int]()
    val list = ListBuffer(1,2,3,4) // 帶初始元素
    println(list(0))    // 獲取第一個元素
    println(list.head)  // 獲取第一個元素
    println(list.tail)  // 獲取除了第一個元素外其他元素組成的列表
    println(list += 5)  // 添加單個元素
    println(list ++= List(6,7)) // 添加一個不可變的列表
    println(list ++= ListBuffer(8,9)) //添加一個可變的列表(刪除同樣)
    println(list.isEmpty) // 列表是否爲空
    list.toList   //根據可變的列表生成不可變列表,原列表不變
    list.toArray  //根據可變的列表生成不可變數組,原列表不變

小結

這裏總結了scala的基本語法,由於主要用於函數式編程,需要形成特殊的語法習慣,熟能生巧!
更加詳細的介紹可以查看教程,很多細節不必死記硬背,只需要大致總結即可,比如數組、映射、集合、列表都有可變和不可變之分等,隨着使用的深入瞭解原理纔是目的。
要抓主要矛盾,解決主要矛盾,作爲大數據編程的利器,下一節會介紹到Spark/Flink的大量業務代碼都會使用到的函數式編程
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章