scala學習---List

本篇知識點歸納

  • List的構造
  • List與Array的區別
  • List的經常使用方法
  • List伴生對象的方法
  • ::和:::操做符的介紹

Scala中使用List

Scala是函數式風格與面向對象共存的編程語言,方法不該該有反作用是函數風格編程的一個重要的理念。方法惟一的效果應該是計算並返回值,用這種方式工做的好處就是方法之間不多糾纏在一塊兒,所以就更加可靠和可重用。另外一個好處(靜態類型語言)是傳入傳出方法的全部東西都被類型檢查器檢查,所以邏輯錯誤會更有可能把本身表現爲類型錯誤。把這個函數式編程的哲學應用到對象世界裏覺得着使對象不可變。
前面一章介紹的Array數組是一個全部對象都共享相同類型的可變序列。比方說Array[String]僅包含String。儘管實例化以後你沒法改變Array的長度。所以,Array是可變的對象。
說到共享相同類型的不可變對象類型,Scala的List類纔是。和數組同樣,List[String]包含的僅僅是String。Scala的List不一樣於Java的java.util.List,老是不可變的(Java的List是可變)。更準確的說法,Scala的List是設計給函數式風格的編程用的。前端

(1)List類型定義以及List的特色:java

 

//字符串類型List
scala> val fruit=List("Apple","Banana","Orange")
fruit: List[String] = List(Apple, Banana, Orange)

//前一個語句與下面語句等同
scala> val fruit=List.apply("Apple","Banana","Orange")
fruit: List[String] = List(Apple, Banana, Orange)

//數值類型List
scala> val nums=List(1,2,3,4,5)
nums: List[Int] = List(1, 2, 3, 4, 5)

//多重List,List的子元素爲List
scala> val list = List(List(1, 2, 3), List("adfa", "asdfa", "asdf"))
list: List[List[Any]] = List(List(1, 2, 3), List(adfa, asdfa, asdf))

//遍歷List
scala> for(i <- list; from=i; j<-from)println(j)
1
2
3
adfa
asdfa
asdf

(2)List與Array的區別:es6

一、List一旦建立,已有元素的值不能改變,可使用添加元素或刪除元素生成一個新的集合返回。
如前面的nums,改變其值的話,編譯器就會報錯。而Array就能夠成功算法

scala>nums(3)=4
<console>:10: error: value update is not a member of List[Int]
              nums(3)=4
              ^

二、List具備遞歸結構(Recursive Structure),例如鏈表結構
List類型和睦他類型集合同樣,它具備協變性(Covariant),即對於類型S和T,若是S是T的子類型,則List[S]也是List[T]的子類型。
例如:編程

scala>var listStr:List[Object] = List("This", "Is", "Covariant", "Example")
listStr:List[Object] = List(This, Is, Covariant, Example)

//空的List,其類行爲Nothing,Nothing在Scala的繼承層次中的最底層
//,即Nothing是任何Scala其它類型如String,Object等的子類
scala> var listStr = List()
listStr:List[Nothing] = List()

scala>var listStr:List[String] = List()
listStr:List[String] = List()

(3)List經常使用構造方法數組

//一、經常使用::及Nil進行列表構建
scala> val nums = 1 :: (2:: (3:: (4 :: Nil)))
nums: List[Int] = List(1, 2, 3, 4)


//因爲::操做符的優先級是從右向左的,所以上一條語句等同於下面這條語句
scala> val nums = 1::2::3::4::Nil
nums:List[Int] = List(1, 2, 3, 4)
至於::操做符的使用將在下面介紹

(4)List經常使用操做app

//判斷是否爲空
scala> nums.isEmpty
res5: Boolean = false

//取第一個元素
scala> nums.head
res6: Int = 1

//取列表第二個元素
scala>nums.tail.head
res7: Int = 2

//取第三個元素
scala>nums.tail.tail.head
res8: Int = 3

//插入操做
//在第二個位置插入一個元素
scala>nums.head::(3::nums.tail)
res11: List[Int] = List(1, 3, 2, 3, 4)

scala> nums.head::(nums.tail.head::(4::nums.tail.tail))
res12: List[Int] = List(1, 2, 4, 3, 4)

//插入排序算法實現
def isort(xs: List[Int]):List[Int] = {
    if(xs.isEmpty) Nil
    else insert(xs.head, issort(xs.tail))
}

def insert(x:Int, xs:List[Int]):List[Int] = {
    if(xs.isEmpty || x <= xs.head) x::xs
    else xs.head :: insert(x, xs.tail)
}

//鏈接操做
scala>List(1, 2, 3):::List(4, 5, 6)
res13: List[Int] = List(1, 2, 3, 4, 5, 6)

//去除最後一個元素外的元素,返回的是列表
scala> nums.init
res13: List[Int] = List(1, 2, 3)

//取出列表最後一個元素
scala>nums.last
res14: Int = 4

//列表元素倒置
scala> nums.reverse
res15: List[Int] = List(4, 3, 2, 1)

//一些好玩的方法調用
scala> nums.reverse.reverse == nums


//丟棄前面n個元素
scala>nums drop 3
res16: List[Int] = List(4)

//獲取前面n個元素
scala>nums take 1
res17: List[Int] = List[1]

//將列表進行分割
scala> nums.splitAt(2)
res18: (List[Int], List[Int]) = (List(1, 2),List(3, 4))

//前一個操做與下列語句等同
scala> (nums.take(2),nums.drop(2))
res19: (List[Int], List[Int]) = (List(1, 2),List(3, 4))

//Zip操做
scala> val nums=List(1,2,3,4)
nums: List[Int] = List(1, 2, 3, 4)

scala> val chars=List('1','2','3','4')
chars: List[Char] = List(1, 2, 3, 4)

//返回的是List類型的元組(Tuple),返回的元素個數與最小的List集合的元素個數同樣
scala> nums zip chars
res20: List[(Int, Char)] = List((1,1), (2,2), (3,3), (4,4))

//List toString方法
scala> nums.toString
res21: String = List(1, 2, 3, 4)

//List mkString方法
scala> nums.mkString
res22: String = 1234

//轉換成數組
scala> nums.toArray
res23: Array[Int] = Array(1, 2, 3, 4)

(5)List伴生對象方法xss

//apply方法
scala>  List.apply(1, 2, 3)
res24: List[Int] = List(1, 2, 3)

//range方法,構建某一值範圍內的List
scala>  List.range(2, 6)
res25: List[Int] = List(2, 3, 4, 5)

//步長爲2
scala>  List.range(2, 6,2)
res26: List[Int] = List(2, 4)

//步長爲-1
scala>  List.range(2, 6,-1)
res27: List[Int] = List()

scala>  List.range(6,2 ,-1)
res28: List[Int] = List(6, 5, 4, 3)

//構建相同元素的List
scala> List.make(5, "hey")
res29: List[String] = List(hey, hey, hey, hey, hey)

//unzip方法
scala> List.unzip(res20)
res30: (List[Int], List[Char]) = (List(1, 2, 3, 4),List(1, 2, 3, 4))

//list.flatten,將列表平滑成第一個無素
scala> val xss =
     | List(List('a', 'b'), List('c'), List('d', 'e'))
xss: List[List[Char]] = List(List(a, b), List(c), List(d, e))
scala> xss.flatten
res31: List[Char] = List(a, b, c, d, e)

//列表鏈接
scala> List.concat(List('a', 'b'), List('c'))
res32: List[Char] = List(a
, b, c)

(6)::和:::操做符介紹編程語言

List中經常使用'::',發音爲"cons"。Cons把一個新元素組合到已有元素的最前端,而後返回結果List。函數式編程

scala> val twoThree = List(2, 3)
scala> val oneTwoThree = 1 :: twoThree
scala> oneTwoThree
oneTwoThree: List[Int] = List(1, 2, 3)

上面表達式"1::twoThree"中,::是右操做數,列表twoThree的方法。可能會有疑惑。表達式怎麼是右邊參數的方法,這是Scala語言的一個例外的狀況:若是一個方法操做符標註,如a * b,那麼方法被左操做數調用,就像a.* (b)--除非方法名以冒號結尾。這種狀況下,方法被右操做數調用。
List有個方法叫":::",用於實現疊加兩個列表。

scala> val one = List('A', 'B')
val one = List('A', 'B')
scala> val two = List('C', 'D')

scala> one:::two
res1: List[Char] = List(A, B, C, D)

 

注意:

類List沒有提供append操做,由於隨着列表變長append的耗時將呈線性增加,而使用::作前綴則僅花費常量時間。若是你想經過添加元素來構造列表,你的選擇是把它們前綴進去,當你完成以後再調用reverse;或使用ListBuffer,一種提供append操做的可變列表,當你完成以後調用toList。

相關文章
相關標籤/搜索