1. 程式人生 > >Scala程式設計(一)

Scala程式設計(一)

Scala程式設計(一)

Scala的特點

Scala是一種多正規化的程式語言,其設計的初衷是為了整合面向物件和函式是程式設計的各種特性,Scala運行於Java平臺(Java虛擬機器),併兼容現有的Java程式(Scala原始碼會被編譯成Java位元組碼,它可以運行於JVM之上,並可以呼叫現有的Java類庫)。

開發環境搭建

1.安裝JDK

Scala原始碼會被編譯成Java位元組碼,它可以運行於JVM之上,並可以呼叫現有的Java類庫)。

2.安裝Scala

windows下安裝

下載Scala

從 Scala 官網地址 http://www.scala-lang.org/downloads

下載 Scala

選用 .zip 的安裝包下載

安裝配置Scala

解壓scala-2.11.8.zip到本地磁碟上

在環境變數中配置Scala的bin目錄路徑

檢測是否安裝成功

IDEA安裝Scala外掛

Configure -> Plugins -> Browse repositories ->
搜尋 Scala 外掛 -> OK -> 重啟 IDEA

使用idea編寫helloworld

object HelloWorld {
  def main(args: Array[String]): Unit = {
  	println("hello,world");
  }
}

Scala基礎

基礎語法需要了解以下幾點:

資料型別、變數、if語句、條件表示式、塊表示式、for語句

1.常用資料型別

Scala 與 Java有著相同的資料型別,

Scala的資料型別相當於Java中資料型別的包裝類

2.宣告變數

Scala的宣告變數的格式:

var 變數名=初始值 val 變數名=初始值

var 變數名:資料型別=初始值 val 變數名:資料型別=初始值

object demo1 {
  def main(args: Array[String]): Unit = {

    var i = 1   //宣告時未指定型別Scala會自動判斷
    val j : Int= 10   //宣告時指定了資料型別

    println("i的值是:" + i)
    println(s"j的值是:$j")   //可使用$加變數名來獲得變數的值

    i = 100   //修改用var定義的變數
    println(s"修改後的i值是:$i")

/*    j = 100
      使用var關鍵字宣告的變數,可以對該變數的值進行修改
      使用val關鍵字宣告的變數(相當於常量),不可以對該變數的值進行修改
         */
  }
}

3.條件表示式

Scala中的常用表示式:和java中的三元運算子類似,但比他強大

Scala的表示式語法:

val result = if(比較運算表示式) 結果1 else 結果2

在給變數賦值時,可以直接使用單支if語句 或 雙支if語句 或 多支if語句

例如: val result = if(num==10) 0 else if(num>10) 1 else -1

object demo2 extends App {
  val num = 2
  val result1 = if(num > 3) 1 else -1
  println(result1)
  //支援混合型別的表示式
  val result2 = if (num > 3) 1 else "error"
  println(result2)
  //if..else if.. else..
  val result3 = if (num >3) 1 else if (num <3) -1 else 0
  println(result3)
}

4.塊表示式

定義變數時可以使用 {} 包含一系列表示式:

object demo3 extends App {
  val a = 10
  val b = 20
  val result = {   //該塊表示式的最後一行表示式的值就是塊的結果
    val num1 = a + b
    val num2 = b - a
    num1    //塊表示式的結果值
  }
  println(result) //值為30
}

5.迴圈for語句

在scala中同樣具有:for迴圈、while迴圈、do…while迴圈

for迴圈語法結構:

for (i <- 表示式/陣列/集合)

object demo4 extends App {
  //迴圈取值
  for (i <- 1 to 10){   //區間1到10(包含1和10)
    println(i)
  }

  for (i <- 1 until 10){   //區間1到10(不包含10)
    println(i)
  }

  for (i <- 1 to 10 if i%3==0){   //新增守衛條件,滿足守衛條件後才輸出
    println(i)    //結果是3,6,9
  }

  //巢狀for
  for (i <- 1 to 5;j <- 6 to 10){
    println(i + "\t" + j)
  }
  //九九乘法表
  for (i <- 1 to 9 ;j <- 1 to 9 if i >= j){
    print(i + "x" + j + "=" + i*j + "\t")
    if (i ==j){
      println()
    }
  }
    
    //通過yield來操作for迴圈中的每一個值
  var a = for (i <- 1 to 10 ) yield i*10
  println(a)
}
while迴圈語法結構:
while(condition)
{
   statement(s);
}
object demo5 extends App {
  var a = 10
  while (a < 20){
    println(s"a的值為:$a")
    a =a + 1
  }
}
do…while 迴圈語法結構

do…while 迴圈與 while 迴圈類似,但是 do…while 迴圈會確保至少執行一次迴圈

do {
   statement(s);
} while( condition );
object demo5 extends App {
  var a = 10
  do {
    println(s"a的值為:$a")
    a =a + 1
  }while(a < 20)
}

函式

Scala語言具有函數語言程式設計思想

函式的定義使用

def 函式名(引數1:型別,引數2:型別…):返回值型別 = { 函式體程式碼實現 }

object demo6 extends App {
  //無參無返回的函式
  function()
  //Unit表示沒有返回值
  def function():Unit = {
  println("沒有返回值引數")
  }

  //有引數有返回的函式
  println(add(2,3))
  //不寫返回值型別,程式會自行判斷返回值型別
  def add(num1:Int,num2 :Int)={
    val sum = num1 + num2
    sum
  }
  //當函式的函式體程式碼只有一行是還可簡寫成如下的程式碼
  print(add2(3,4))
  def add2(num1:Int,num2 :Int) = num1 + num2

  //函式中的引數預設是使用val定義,不能對引數的值進行修改
  //匿名函式的左邊是引數列表右邊是函式體
  //匿名函式的語法格式:(引數:型別 , …)  =>  函式體
  print(sum(5,6))
  val sum = (num1:Int,num2 :Int) => num1 + num2

}

函式中的引數

預設引數:

在Scala中允許在定義函式時,給函式中的引數設定預設值。在呼叫函式時如沒有給帶有預設值的引數傳值,則會

使用函式的預設引數值

格式:def 函式名(引數:引數型別=預設值 , 引數:引數型別=預設值) : 返回值型別 = { 函式體 }

帶名引數:

一般情況下在函式呼叫時,函式的引數傳遞是按照函式定義時的引數順序一個個傳遞。但是我們也可以通過指定函式引數名,並且不需要按照順序向函式傳遞引數

在使用帶名引數時,要求:呼叫的函式的中書寫的引數名稱必須和函式定義時所書寫的引數名稱保持一致

可變引數:

Scala 允許你指明函式的最後一個引數可以是重複的,即我們不需要指定函式引數的個數,可以向函式傳入可變長度引數列表

語法格式: def 函式名( 引數 : 引數型別*): 返回值型別 = { … }

Scala 是通過在引數的型別之後放一個星號來設定可變引數(可重複的引數)

object demo7 extends App {
  printStrings("hadoop","spark","scala")
  def printStrings  (strs : String*) ={
    for (str <- strs){
      print(str + "\t")
    }
  }
}

陣列、元組、集合

陣列

Scala 語言中提供的陣列是用來儲存固定大小的同類型元素

陣列的第一個元素索引為0,最後一個元素的索引為元素總數減1

語法格式1:

var 陣列名: Array[元素型別] = new Array[元素型別](陣列大小)

簡化: var 陣列名 = new Array[元素型別](陣列大小)

語法格式2:

var 陣列名 = Array(元素1,元素2,元素3,…)

說明:在Scala語言中,除了有不可變的陣列外,還有可變陣列

​ 不可變陣列:陣列的長度不能改變,但陣列中儲存的元素可以改變

​ 可變陣列:陣列的長度可以改變,陣列中儲存的元素也可以改變

陣列的使用

object demo8 extends App {
  var arr = new Array[Int](3)
  //通過角標賦值
  arr(0) = 1;
  arr(1) = 2;
  arr(2) = 3;
  //遍歷
  for (i <- arr){
    println(i)
  }

  //陣列常用演算法
  val arr1 = Array(1,3,5,4)
  //求和
  val sum = arr1.sum
  println(s"和為:$sum")
  //最大值
  val max = arr1.max
  println(s"最大值為:$max")
  //最小值
  val min = arr1.min
  println(s"最小值為:$min")
  //排序
  val arr2 = arr1.sorted  //預設升序 排序不會破壞元陣列的順序需要用新陣列接收
  for (i <- arr2) print(i + "\t")
  println("\n------------")
  //從大到小
  val arr3 = arr1.sortWith(_>_)
  for (i <- arr3) print(i + "\t")
  println("\n------------")

  println(arr.mkString("|"))
  println(arr.mkString("start:","-","end"))
}
變長陣列

掌握變長陣列的定義及使用(當陣列中所儲存元素的個數不固定時使用變長陣列)
Scala中的Array屬於固定長度的陣列,同樣scala也提供了可變長度的陣列:ArrayBuffer如果想使用陣列緩衝,需要匯入: import scala. collection. mutable. ArrayBuffer

import scala.collection.mutable.ArrayBuffer

object demo9 extends App {
  var arr = ArrayBuffer[Int]()
  //追加元素
  arr += 10
  arr.append(10)
  arr += (20,30,40)
  //追加陣列
  arr ++= Array(50,60)
  arr ++= ArrayBuffer(100,200)
  //向陣列指定的位置新增
  arr.insert(0, 8,9)
  //刪除陣列中的元素
  arr.remove(0)
  //刪除從角標1開始向後取三個元素
  arr.remove(1,3)
  
  print(arr)
}

元組

Scala元組將固定數量的元素組合在一起,以便它們可以作為一個整體傳遞。與陣列或列表不同, 元組可以容納不

同類型的物件,但它們也是不可變的

元組可以理解為:是不同型別的值的聚集

元組的表示:通過將不同的值用小括號括起來,即表示元組

建立元組格式: val tuple = (元素,元素,…)

元組是型別Tuple1,Tuple2,Tuple3等等。 目前在Scala中只能有22個上限,如果您需要更多個元素, 那麼可以

使用集合而不是元組

獲取元組中的值格式:使用下劃線加腳標 ,例如 t._1 t._2 t._3

注意元組中的元素角標是從1開始的

集合

Scala的集合有三大類: List、Set、Map(對映),所有的集合都擴充套件自Iterable在Scala中集合有可變(mutable)和不可變(immutable)兩種型別,immutable 型別的集合初始化後就不能改變了

list集合

不可變list集合
object demo10 extends App {
  val list = List[Int](1,2,3)
  //list(0) = 100   //報錯
  println(list)
  /**
    * 在Scala中列表要麼為空(Nil表示空列表)
    * 要麼是一個head元素加上一個tail列表
    *
    */
  //定義一個空集合
  val list1 = Nil
  println(list1)
  //head:返回第一個元素
  println(list.head)
  //tail:返回除了第一個元素以外的其他元素
  println(list.tail)

  //list集合的使用
  //在list集合的頭部新增新元素,並生成新的集合
  val list11 = 1 +: list
  println(list11)
  //把要新增的元素和原集合作為新集合的頭和尾
  val list12 = 1 :: list
  println(list12)
  //在集合尾部新增新元素,並生成新的集合
  val list13 = list :+ 9
  println(list13)
}
可變list集合

import scala.collection.mutable._

import scala.collection.mutable.ListBuffer

object demo11 extends App {
  //集合基本使用
  val list = ListBuffer[Int](1,2,3)
  //追加元素
  list += 4
  list.append(5)
  //插入元素
  list.insert(0,0)
  println(list)
  //修改元素
  list(0) = 10
  //刪除元素
  list.remove(0)
  list.remove(0,2)
}

合併集合

object demo12 extends App {
  val list1 = ListBuffer[Int](1,2,3)
  val list2 = ListBuffer[Int](4,5,6)
  //合併集合(追加到末尾),不會產生新的集合
  list1 ++= list2
  println(list1)
  //合併集合生成新的集合
  val list3 = list1 ++ list2
  println(list3)
}

Set集合

不可變Set集合

Set代表一個沒有重複元素的集合;將重複元素加入Set是沒有用的,而且 Set 是不保證插入順序的,即 Set 中的元素是亂序的。
定義格式 : val set=Set(元素,元素,…)

object demo13 extends App {

  //不可變的set集合
  val set = Set(3,5,7,9)
  //新增元素,生成新的集合,重複的元素只有一個
  val set1 = set + (3,5,6)
  println(set1)
  //刪除元素,生成新的集合
  val set2 = set - (5,6)
  println(set2)
  //集合合併
  val set11 = Set(1,2,3,4)
  val set12 = Set(3,4,5,6)
  val newSet = set11 ++ set12
  println(s"集合的並集為$newSet")
  //集合的交集
  val newSet1 = set11 & set12
  println(s"集合的交集為:$newSet1")
}
可變的set集合
object demo14 extends App {
  val set = mutable.Set(3,4,5)
  //新增元素(不會生成新的集合)
  //重複元素不新增
  set.add(4)
  set.+=(6)
  println(set)
  //刪除元素
  //使用remove,返回布林型別的結果
  println(set.remove(0))
  set.-=(3)
  println(set)
  //合併集合(不生成新的集合)
  val set1 = mutable.Set(1,2,3)
  val set2 = mutable.Set(3,4,5)
  set1.++=(set2)
  println(set1)
}

Map集合

定義Map集合:
val map=Map(鍵->值 ,鍵->值 ,…)

val map=Map((鍵,值), (鍵,值) , (鍵,值) , …) //利用元組構建

不可變Map集合
object demo15 extends App {
  //不可變的Map集合(操作時都會產生新的Map集合)
  val map = Map("sh"->"shanghai","bj"->"beijing")
  //新增,修改都可用
  val map1 = map.+("tj"->"tianjin")
  println(s"map1集合:$map1")
  //刪除
  val map2 = map.-("sh")
  println(s"map2集合:$map2")
  //獲取元素
  val value : Option[String]= map.get("bj")
  //val value = map("bj") 直接使用Key
  println(s"value的值為:$value")
}

Scala Option(選項)型別用來表示一個值是可選的(有值或無值)。
Option[T] 是一個型別為T的可選值的容器:
如果值存在, Option[T] 就是一個 Some[T]
如果不存在, Option[T] 就是物件 None

遍歷和合並

object demo16 extends App {
  val map1 = Map("sh"->"shanghai","bj"->"beijing")
  val map2 = Map("sh"->"shanghai","nj"->"nanjing")
  //遍歷
  for (k <- map1.keys){
    println(s"Key值為:$k")
    print(s"value值為:" + map1(k))
  }
  map2.keys.foreach(k =>{
    println(s"Key值為:$k")
    print(s"value值為:" + map2(k))
  })

  //合併集合
  //末尾新增
  val newMap1 = map1.++(map2)
  println("末尾新增"+newMap1)
  //頭部新增
  val newMap2 = map1.++:(map2)
  println("頭部新增"+newMap2)
 }
可變Map集合
import scala.collection.mutable

object demo17 extends App {
  val map :mutable.Map[String,Int]= mutable.Map()
  //新增kv元素
  map("lisi") = 12
  map.put("zhangsan",20)
  map.+=("wangwu"->13)
  //刪除元素
  map.remove("lisi")
  map.-=("wangwu")
  println("map集合:"+ map)
}