相見恨晚的 scala - 01 [ 基礎 ]

簡潔到不行,多一個分號都是不該該。java

學習筆記:python

centOS 下安裝 scala 和安裝 jdk 一毛同樣 . mysql

1 . 不一樣於 Java 的變量聲明 :( 可是和 js 很像 )算法

/**
  * Created by msym on 2017/7/3.
  */
object VarTest {
  def main(args: Array[String]) {
    //使用val定義的變量值是不可變的, 至關於java裏用final修飾的變量
    val i = 1
    //使用var定義的變量是可變的,可是在Scala中鼓勵使用val, 若是必定須要可變化的變量纔會使用 var
    var s = "hello"
    //Scala編譯器會自動推斷變量的類型, 必要的時候能夠指定類型
    //變量名在前,類型在後
    val str: String = "msym"
  }
}

2 . 不一樣於 Java 的數據類型 : ( 無基本數據類型, 只有引用型數據類型 )sql

數據類型 解釋

備註編程

Byte

8位有符號補碼整數, -128~127數組

這些都是引用類型, 沒有基本類型app

Short 16位有符號補碼整數, -215~215-1  
Int 32位有符號補碼整數, -231~231-1  
Long 64位有符號補碼整數, -263~263-1  
Float 32位單精度浮點數  
Double 64位單精度浮點數  
Char 字符, 和 Java同樣都是 Unicode編碼  
Boolean true 或 false  
String 字符串  
Null null 或者空引用  
Unit 與 Java中 void相同, 表示沒有返回值.
這個類只有一個實例, 就是一對圓括號 ()
 
Nothing 最底層的類, 是任何類的子類  
Any 超類, 等同於 Java中 Object類  
AnyRef 全部引用類的基類  

何時用到了超類呢 ? 以下 :函數式編程

image

由於不能肯定 res 的類型, 只有在運行的時候纔會肯定其類型, 函數

因此 res的類型是超類 Any類型, 最終 res的類型仍是 String類型.


3 . 不一樣於 java 的 for 循環:

/**
  * Created by msym on 2017/7/3.
  */
object Test {
  def main(args: Array[String]) {
    //普通for循環
    var a = 0
    for (a <- 1 to 10){
      print(a + ", ")
    }
    println()
    //不包含10
    for(a <- 1 until 10){
      print(a + ", ")
    }
    println()
    //不包含9,步長爲2
    for(a<- 1 until(9, 2)){
      print(a + ", ")
    }
    println()
    //取笛卡爾積的for
    var b = 0
    var c = 0
    for(a <- 1 to 10;b <- 1 to 9){
      c = c + 1
      println("a: " + a)
      println("b: " + b)
    }
    //c輸出爲90,也就是循環了90次
    println("c:" + c)

    //遍歷集合
    var mlist = List(10,2,13)
    for (a <- mlist){
      print(a + ", ")
    }
    println()
    //多條件過濾
    for(a<-mlist if a!=2;if a>10){
      print(a + ", ")
    }
    println()
    //使用yield關鍵字存儲for循環的每次的結果
    var d = 0;
    val numList = List(1,2,3,4,5,6,7,8,9,10);

    // for 循環,注意這裏使用的是大括號
    var retVal = for{ d <- numList
                      if d != 3; if d < 8
    }yield d

    // 輸出返回值
    var e = 0
    for( e <- retVal){
      println( "Value of d: " + e );
    }

  }
}

4 . 不一樣於 Java的方法 (scala裏面方法和函數不同, 定義方法的關鍵字和python同樣)

    // def是定義方法的關鍵字, 形參寫在類型前面, 使用冒號分割,
    // 返回值寫在圓括號後面, 這裏的返回值是Unit, 也就是void,
    // 別忘了等號, 大括號是函數體, 若是隻有一行, 能夠省略大括號
    def show(arr : Array[Int]): Unit ={
      for (i <- arr)
        print(i + ", ")
    }
    //調用方法
    show(Array(1, 2, 3, 4))

image

須要留意方法的簽名和函數的簽名 .

5 . scala中的函數 ( 暫時不是特別理解函數式編程, 只以爲用着很爽 )

  //定義一個函數fun1
  //使用val或者var定義函數
  //圓括號內是函數簽名, =>後面是函數體
//返回值和方法同樣,寫在簽名後面,若是沒有返回值,能夠不寫,或者寫:Unit
val fun1 = (x:Int, y:Int) => x + y

方法到函數的轉換: 看圖

image

     下劃線和 add1之間的空格不能丟, 雖然這裏調用方法和函數的形式是同樣的, 不是說函數和方法同樣, 借一句名言, " 在函數式編程中, 函數是 '頭等公民', 他能夠像任何其餘數據類型同樣被傳遞和操做 "

     值得關注的是函數的簽名, 每一個函數的簽名最後都有一個<function數字> 的樣式, 這個的數字表明的是函數須要的函數個數, 這裏實際上是函數體, 只是使用 <function數字>代替了 .

另一種函數的定義:

image

      這種纔是經常使用的函數的定義方式,  其中 f1表明函數名, :(Int, Double)表明的是傳入的參數列表, =>後的 Double表明的是返回值類型 [ 能夠是任何類型, 包括元組 ] , = 後面的是函數體 .


6 . 不一樣於 Java的數組

scala 中數組能夠存儲不一樣數據類型的元素 , 當存儲不一樣數據類型時, 數組中的類型直接提高爲 Any類型.

其實就是Java中數組元素爲 Object類型。

image

scala 中數組分爲兩種 : 定長數組和變長數組 [ 一樣, List 集合也是, 分爲定長和變長 ]

import scala.collection.mutable.ArrayBuffer


object ArrayTest {

  def main(args: Array[String]) {

    //初始化一個長度爲8的定長數組,其全部元素均默認爲0
    val arr1 = new Array[Int](8)
    //直接打印定長數組,內容爲數組的hashcode值
    println(arr1)
    //將數組轉換成數組緩衝,就能夠看到原數組中的內容了
    //toBuffer會將數組轉換數組緩衝
    println(arr1.toBuffer)

    //注意:若是new,至關於調用了數組的apply方法,直接爲數組賦值
    //初始化一個長度爲1的定長數組, 只有一個元素, 也就是10
    val arr2 = Array[Int](10)
    println(arr2.toBuffer)

    //定義一個長度爲3的定長數組
    val arr3 = Array("hadoop", "storm", "spark")
    //使用()來訪問元素
    println(arr3(2))

    //變長數組(數組緩衝)
    //若是想使用數組緩衝,須要導入import scala.collection.mutable.ArrayBuffer包
    val ab = ArrayBuffer[Int]()
    //向數組緩衝的尾部追加一個元素
    //+=尾部追加元素
    ab += 1
    //追加多個元素
    ab += (2, 3, 4, 5)
    //追加一個數組++=
    ab ++= Array(6, 7)
    //追加一個數組緩衝
    ab ++= ArrayBuffer(8,9)
    //打印數組緩衝ab

    //在數組某個位置插入元素用insert, 在0的位置插入 -1和0兩個元素
    ab.insert(0, -1, 0)
    //刪除數組某個位置的元素用remove, 從第八位開始, 移除兩個元素
    ab.remove(8, 2)
    println(ab)

  }
}

7 . scala 中的元組

      第一次聽到元組這個東西仍是在 mysql中,表明着一行記錄,在 scala中也能夠這樣理解,一行記錄,能夠存儲各類不一樣的數據類型值。

建立元組:使用圓括號

object Test {
   def main(args: Array[String]) {
      val t = ("Scala", "hello", 12)
      println("msym: " + t._3 )
   }
}

獲取元組中的值使用的的是 「._」,好比上面獲取的是元組的第三個元素。

建立元組能夠直接用圓括號,也能夠這樣用

val t = Tuple3("Scala", "hello", 12)

這裏的 Tuple 表明元組,數字 3 表明元組中元素的個數,最大的只能爲 22,再大就能夠選用集合了。

      圓括號內只有兩個元素的元組叫作對偶元組, 對偶元組在下面的 Map集合中用到比較多, 能夠說, Map 中存儲的就是對偶元組 .

對偶元組手動建立, 也能夠經過數組的拉鍊操做生成, 下面是數組的拉鍊操做生成 :

image

上面先建立了兩個數組, 而後經過 zip拉鍊操做, 合成了一個新數組, 新數組中的元素時以元組的形式存在的 .

注 :

     當進行拉鍊操做時, 合成數組的長度是以短的那個數組長度爲準, 較長的那個數組的多餘的元素不會被添加到新數組中 .

 

 8. scala中的集合

scala 中的集合有三大類:

  1. 列表 List
  2. 集 Set
  3. 映射 Map

      和 Java中同樣, List底層是數組形式, 存取順序一致, 可重複; Set集合不能存儲重複元素, 存取順序不一致, 底層使用的是 Hash算法, Map是雙鏈集合, key不能重複, 存取順序也不能保證一致 .

     上面三種集合都擴展自 Iterable 特性,在 scala中集合有可變(mutable)和不可變(immutable)兩種類型,immutable類型的集合初始化後就不能改變了,(可是和val 又不一樣,val是引用不能改, 內容能夠改; immutable是內容都不能改, 引用是能夠改變的)

1 . 列表 List:

      不可變列表

object ImmutListTest {

  def main(args: Array[String]) {
    //建立一個不可變的集合
    val lst1 = List(1,2,3)
    //將0插入到lst1的前面生成一個新的List
    val lst2 = 0 :: lst1
    val lst3 = lst1.::(0)
    val lst4 = 0 +: lst1
    val lst5 = lst1.+:(0)

    //將一個元素添加到lst1的後面產生一個新的集合
    val lst6 = lst1 :+ 3

    val lst0 = List(4,5,6)
    //將2個list合併成一個新的List
    val lst7 = lst1 ++ lst0
    //將lst0插入到lst1前面生成一個新的集合
    val lst8 = lst1 ++: lst0

    //將lst0插入到lst1前面生成一個新的集合
    val lst9 = lst1.:::(lst0)

    println(lst9)
  }
}

      可變列表:

import scala.collection.mutable.ListBuffer

object MutListTest extends App{
  //構建一個可變列表,初始有3個元素1,2,3
  val lst0 = ListBuffer[Int](1,2,3)
  //建立一個空的可變列表
  val lst1 = new ListBuffer[Int]
  //向lst1中追加元素,注意:沒有生成新的集合
  lst1 += 4
  lst1.append(5)

  //將lst1中的元素最近到lst0中, 注意:沒有生成新的集合
  lst0 ++= lst1

  //將lst0和lst1合併成一個新的ListBuffer 注意:生成了一個集合
  val lst2= lst0 ++ lst1

  //將元素追加到lst0的後面生成一個新的集合
  val lst3 = lst0 :+ 5
}

2 . Set

      不可變的Set

import scala.collection.immutable.HashSet

object ImmutSetTest extends App{
  val set1 = new HashSet[Int]()
  //將元素和set1合併生成一個新的set,原有set不變
  val set2 = set1 + 4
  //set中元素不能重複
  val set3 = set1 ++ Set(5, 6, 7)
  val set0 = Set(1,3,4) ++ set1
  println(set0.getClass)
}

    可變的 Set

import scala.collection.mutable

object MutSetTest extends App{
  //建立一個可變的HashSet
  val set1 = new mutable.HashSet[Int]()
  //向HashSet中添加元素
  set1 += 2
  //add等價於+=
  set1.add(4)
  set1 ++= Set(1,3,5)
  println(set1)
  //刪除一個元素
  set1 -= 5
  set1.remove(2)
  println(set1)
}

3 . Map

import scala.collection.mutable

object MutMapTest extends App{
  val map1 = new mutable.HashMap[String, Int]()
  //向map中添加數據
  map1("spark") = 1
  map1 += (("hadoop", 2))
  map1.put("storm", 3)
  println(map1)

  //從map中移除元素
  map1 -= "spark"
  map1.remove("hadoop")
  println(map1)
}

 

雜項:

   1 . 參數默認值 :

        這點和 C#同樣了,就是在形參列表上指定默認值,若是調用時不指定參數,那麼就使用默認值,其實這點會和 java中的重載會有一點衝突,java之因此不支持參數默認值,是由於有重載,若是二者都存在會致使二義性。

object Test {
   def main(args: Array[String]) {
       //不指定參數,返回12
        println( "Res1: " + add() );
       //指定一個參數,返回8
        println( "Res2: " + add(1) );
       //指定兩個參數,返回3
        println( "Res3: " + add(1, 2) );
   }
   def add( a:Int=5, b:Int=7 ) : Int = {
      var sum:Int = 0
      sum = a + b
      return sum
   }
}

 

 

 

 

 

 

 

1

相關文章
相關標籤/搜索