Chapter 16 《Working with Lists》


列表
    1. 不同于數(shù)組蜒犯,列表的元素是不能改變的絮供,列表是鏈表子巾。
    1. 同一個(gè)列表的所有元素都必須是相同類型的帆赢。元素類型為T的列表類型為List[T]。注意T可能是Any這樣的父類线梗。ScalaList是協(xié)變的椰于,List[Child]List[Father]的子類∫巧Γ空列表的類型為List[Nothing]瘾婿,因此是任何List[T]的子類型。可以使用空列表List()也就是Nil來(lái)構(gòu)建列表偏陪。
    1. 所有的列表都構(gòu)建自兩個(gè)基礎(chǔ)單元抢呆,一個(gè)是Nil,一個(gè)是::笛谦。::是中綴表示符抱虐,在列表前添加元素。

列表的基本操作

head饥脑,tail恳邀,isEmptyheadtail只對(duì)非空列表有定義灶轰,否則會(huì)拋出異常轩娶。


列表模式
    1. 列表也可以使用模式匹配解開(kāi)。
      a::b::list可以匹配長(zhǎng)度大于等于2的列表框往。a::Nil表示只有一個(gè)元素的列表,推薦使用列表模式來(lái)對(duì)列表進(jìn)行解構(gòu)闯捎。
    1. 匹配列表最常見(jiàn)的方式是區(qū)分空列表和非空列表椰弊。

List的初階方法

入?yún)⒅袥](méi)有函數(shù)的方法成為稱為方法。

    1. 拼接兩個(gè)列表:::
    • :::入?yún)閮蓚€(gè)列表瓤鼻,返回結(jié)果為包含了這兩個(gè)列表所有元素的一個(gè)列表秉版,列表的返回類型是兩個(gè)列表元素類型繼承樹(shù)上的最近公共父節(jié)點(diǎn)。也是右結(jié)合的操作符茬祷。
    • 對(duì)列表的操作用的比較多的是分而治之的思想清焕。許多對(duì)列表的算法都首先使用模式匹配將輸入的列表切分為更小的樣例,這是分的思想祭犯,然后對(duì)每個(gè)樣例構(gòu)建對(duì)應(yīng)的結(jié)果秸妥,如果結(jié)果是一個(gè)非空的列表,那么這個(gè)列表的局部可以通過(guò)遞歸的調(diào)用同一個(gè)算法來(lái)實(shí)現(xiàn)沃粗,這是治的思想粥惧。
    1. 獲取列表長(zhǎng)度:length
      這個(gè)不同于數(shù)組,需要更長(zhǎng)的時(shí)間最盅,所以如果使用xs.isEmpty的時(shí)刻突雪,最好不要使用xs.length == 0isEmpty直接定義在了::類和Nil類中涡贱。
    1. 訪問(wèn)列表的末端:initlast咏删,和head以及tail是對(duì)偶方法。
      當(dāng)應(yīng)用到空列表的時(shí)候會(huì)出錯(cuò)问词。headtail在訪問(wèn)的時(shí)候消耗的常量時(shí)間督函,但initlast消耗的是線性時(shí)間,所以一般使用的都是headtail
    1. 反轉(zhuǎn)列表:reverse
      如果在算法中需要頻繁的訪問(wèn)列表的末尾元素,可以先將列表進(jìn)行反轉(zhuǎn)侨核,然后再將列表反轉(zhuǎn)回原樣草穆。
    1. 前綴和后綴:drop,take搓译,splitAt
      take返回前n個(gè)元素悲柱,如果n>list.length,那么就返回整個(gè)列表些己;
      drop表示丟棄前n個(gè)元素豌鸡,如果n>list.length,那么就返回空列表段标;
      splitAt操作將列表從指定的位置切開(kāi)涯冠,生成對(duì)偶(list take n, list drop n)spiltAt會(huì)避免list的兩次遍歷逼庞,結(jié)果是(list take n, list drop n)蛇更,并不代表實(shí)現(xiàn)也是這么實(shí)現(xiàn)的。
    1. 元素選擇:applyindices
      apply支持從對(duì)列表的隨機(jī)訪問(wèn)赛糟,相對(duì)于數(shù)組而言在列表中直接使用下標(biāo)并不是很常見(jiàn)派任。 a apply b可以簡(jiǎn)寫(xiě)為a(b),編譯器會(huì)進(jìn)行展開(kāi)璧南。list(n)的耗時(shí)跟下標(biāo)n成正比掌逛。
      indices方法返回指令列表所有有效下標(biāo)的組合。
    1. 扁平化列表:flatten
      接收一個(gè)列表的列表并將扁平化司倚,返回單個(gè)列表豆混。flatten函數(shù)只能扁平化一層的嵌套。只能應(yīng)用與所有元素都是列表的列表动知,否則會(huì)拋出異常皿伺。
    1. 對(duì)列表使用zipunzip
      zip入?yún)閮蓚€(gè)列表,返回一個(gè)元素是對(duì)偶類型的列表拍柒。如果兩個(gè)列表長(zhǎng)度不同心傀,則丟棄沒(méi)有匹配上的元素,zipWithIndex拆讯,可以將元素和下標(biāo)zip起來(lái)脂男,是常見(jiàn)的應(yīng)用。元組的列表也可以只用unzip來(lái)轉(zhuǎn)換成為列表元組种呐。unzipzip應(yīng)用的都是對(duì)偶宰翅,三個(gè)元素組成的元組是無(wú)法應(yīng)用的。
    1. 顯示列表:toStringmkString爽室,addString
      toString返回列表的標(biāo)準(zhǔn)字符串表現(xiàn)形式:List(a, b, c, d, e)汁讼。
      如需要不同的表現(xiàn)形式,則需要使用mkString,入?yún)⒂腥齻€(gè)嘿架,pre瓶珊,seperator,post耸彪。有重載的版本伞芹,xs.mkstring 表示元素之間的分隔符為空格,入?yún)⒂幸粋€(gè)的版本表示prepost都是空字符串蝉娜。
      mkString還有一個(gè)變種唱较,就是addStringaddString接受一個(gè)StingBuilder召川,將生成的字符串添加到StringBuilder上而不是直接返回南缓。addStringmkString這兩個(gè)方法繼承自List的超特質(zhì)Traversable,所以可以用在所有其他集合類型上荧呐。
    1. 轉(zhuǎn)換列表:iterator, toArray, copyToArray
      toArray可以轉(zhuǎn)換一個(gè)ListArray汉形;
      toList可以轉(zhuǎn)換一個(gè)ArrayList
      copyToArray有兩個(gè)入?yún)⒈恫渲幸粋€(gè)是目標(biāo)array获雕,目標(biāo)array必須足夠大,能夠容納整個(gè)列表收捣。可以通過(guò)iterator來(lái)使用迭代器訪問(wèn)列表中的元素庵楷。
      msort[T](less: (T, T) => Boolean)(xs: List[T])使用currying可以進(jìn)行函數(shù)的定制方便用戶使用罢艾,例如intSort = msort((x:Int, y:Int) => x < y) _是部分應(yīng)用函數(shù),缺少一個(gè)參數(shù)尽纽,使用intSort(List(1, 3, 4))就可以進(jìn)行排序咐蚯。同樣的可以定制intReverseSort = msort((x:Int, y:Int) => x > y) _

List類的高階方法

許多對(duì)列表的操作都有相似的結(jié)構(gòu),有一些模式反復(fù)出現(xiàn)弄贿。入?yún)⒅杏泻瘮?shù)的方法就是高階方法春锋。

    1. 對(duì)列表做映射:map, flatMap, foreach
      map操作接收T=>U函數(shù),生成List[U]差凹。
      flatMap操作接收T=>List[U]期奔,將所有的結(jié)果拼起來(lái)生成List[U]
      foreach的函數(shù)類型為T=>Unit危尿,并沒(méi)有列表類型的結(jié)果被組裝出來(lái)呐萌,賦值運(yùn)算的結(jié)果類型為Unit,值為()谊娇。
    1. 過(guò)濾列表:filter, partition, find, takeWhile, dropWhile, span
      filter接收一個(gè)判斷函數(shù)肺孤,T => Boolean,列表元素的類型為T
      partition類似filter,接收一個(gè)判斷函數(shù)赠堵,T => Boolean小渊,生成的是一對(duì)列表元組,元組中的第一個(gè)列表包含了所有前提條件為true的元素茫叭,第二個(gè)列表包含了所有前提條件為false的元素酬屉。
      find方法和``filter類似,返回滿足給定條件的第一個(gè)元素杂靶,而不是所有元素梆惯,接收一個(gè)判斷函數(shù),返回的是Option類型的值吗垮。
      takeWhiledropWhile接收一個(gè)判斷函數(shù)為前提條件垛吗,takeWhile返回列表中滿足條件的最長(zhǎng)前綴,dropWhile去除列表中滿足條件的最長(zhǎng)前綴烁登。
      span方法生成列表元組:(list takeWhile p怯屉,list dropWhile p),類似于splitAt饵沧,span不會(huì)重復(fù)遍歷列表锨络。
    1. 對(duì)列表的前提條件檢查:forAllexists
      返回的都是布爾值
    1. 折疊列表:/::\
      /:為是左折疊,和foldLeft是一樣的狼牺,(num /: xs)(_ + _)
      可以使用(word.head /: word.tail)(_ + " " + _)去除最前面word之前多余的空格羡儿。
      :\為右折疊,和foldRight是一樣的是钥,(xs :\ num)(_ + _)
      對(duì)于結(jié)合性的操作掠归,右折疊和左折疊是等效的,對(duì)于不同的操作可能存在執(zhí)行效率上的差異悄泥。
    1. 列表排序:sortWith
      接收一個(gè)比較函數(shù)compare虏冻,對(duì)列表進(jìn)行排序,表達(dá)式x compare yx出現(xiàn)在y之前應(yīng)返回true

List伴生對(duì)象的方法

之前的都是List類的方法弹囚,List伴生對(duì)象中的方法是可以在全局訪問(wèn)的厨相。

    1. 從元素創(chuàng)建列表:List.apply
      當(dāng)伴生對(duì)象存在apply函數(shù)時(shí),可使用()來(lái)代替apply鸥鹉。也就是說(shuō)List(1,2,3)List.apply(1,2,3)是相同的效果蛮穿。
    1. 創(chuàng)建數(shù)值區(qū)間:List.range
      List.range(from, until, step:option)until不是列表的一部分毁渗。
    1. 創(chuàng)建相同元素的列表:List.fill
      fill方法創(chuàng)建包含0個(gè)或者多個(gè)同一個(gè)元素拷貝的列表绪撵,第一個(gè)參數(shù)列表確定列表的維度以及每一維度的長(zhǎng)度;第二個(gè)參數(shù)列表是需要拷貝的元素
    1. 表格化一個(gè)函數(shù):List.tabulate
      相同與fill方法祝蝠,但是列表中的值是通過(guò)給定函數(shù)計(jì)算出來(lái)的音诈,計(jì)算與維度長(zhǎng)度有關(guān)
    1. 拼接多個(gè)列表:List.concat
      將多個(gè)列表的元素拼接起來(lái)

同時(shí)處理多個(gè)列表

元組的zipped方法將若干通用的操作一般化了幻碱,不再只是針對(duì)單個(gè)列表而是能夠同時(shí)處理多個(gè)列表。zip會(huì)將所有有值的元素zip起來(lái)细溅,多余的元素會(huì)被丟棄褥傍。


Scala類型推斷算法
  • Scala的類型推斷是基于程序流的,局部的喇聊,對(duì)于方法調(diào)用m(args)恍风,如果知道m的類型,可以將該類型運(yùn)用到之后的運(yùn)算中誓篱。Scala類型推斷算法會(huì)考慮第一個(gè)參數(shù)列表里的所有入?yún)㈩愋团蟊幔?code>currying的函數(shù)中,后面的參數(shù)列表并不會(huì)用于類型推斷窜骄。
  • 所以如果入?yún)⒅杏蟹呛瘮?shù)入?yún)⒑秃瘮?shù)入?yún)⒔跄迹瑢⒑瘮?shù)入?yún)为?dú)放在最后一個(gè)列表中,這樣方法的正確實(shí)例類型可以從非函數(shù)入?yún)⑼茢喑鰜?lái)邻遏,而這個(gè)類型又能被繼續(xù)用于對(duì)函數(shù)入?yún)⒆鲱愋蜋z查糠亩。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市准验,隨后出現(xiàn)的幾起案子赎线,更是在濱河造成了極大的恐慌,老刑警劉巖糊饱,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垂寥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡另锋,警方通過(guò)查閱死者的電腦和手機(jī)矫废,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)砰蠢,“玉大人,你說(shuō)我怎么就攤上這事唉铜√ú眨” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵潭流,是天一觀的道長(zhǎng)竞惋。 經(jīng)常有香客問(wèn)我,道長(zhǎng)灰嫉,這世上最難降的妖魔是什么拆宛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮讼撒,結(jié)果婚禮上浑厚,老公的妹妹穿的比我還像新娘股耽。我一直安慰自己,他們只是感情好钳幅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布物蝙。 她就那樣靜靜地躺著,像睡著了一般敢艰。 火紅的嫁衣襯著肌膚如雪诬乞。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天钠导,我揣著相機(jī)與錄音震嫉,去河邊找鬼。 笑死牡属,一個(gè)胖子當(dāng)著我的面吹牛票堵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播湃望,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼换衬,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了证芭?” 一聲冷哼從身側(cè)響起瞳浦,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎废士,沒(méi)想到半個(gè)月后叫潦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡官硝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年矗蕊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氢架。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡傻咖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出岖研,到底是詐尸還是另有隱情卿操,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布孙援,位于F島的核電站害淤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拓售。R本人自食惡果不足惜窥摄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望础淤。 院中可真熱鬧崭放,春花似錦哨苛、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至道伟,卻和暖如春迹缀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜜徽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工祝懂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拘鞋。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓砚蓬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親盆色。 傳聞我的和親對(duì)象是個(gè)殘疾皇子灰蛙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 〇、前言 本文共108張圖隔躲,流量黨請(qǐng)慎重摩梧! 歷時(shí)1個(gè)半月,我把自己學(xué)習(xí)Python基礎(chǔ)知識(shí)的框架詳細(xì)梳理了一遍宣旱。 ...
    Raxxie閱讀 18,954評(píng)論 17 410
  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,793評(píng)論 0 38
  • 前言 人生苦多仅父,快來(lái) Kotlin ,快速學(xué)習(xí)Kotlin浑吟! 什么是Kotlin笙纤? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,209評(píng)論 9 118
  • 最近忙瘋了,又是受傷又是各種充電學(xué)習(xí)ing 有幸聽(tīng)到幾位云南名嘴談閱讀组力,閱讀對(duì)于一個(gè)孩子的成長(zhǎng)到底有多重要呢省容??jī)H是...
    蕙心紈質(zhì)閱讀 118評(píng)論 0 0
  • 我羨慕那些能夠輕輕松松的就把自己委屈跟不開(kāi)心的講出來(lái),我羨慕那些家庭美滿不知世間丑態(tài)的天真小孩燎字,我羨慕那些拿不起又...
    啊曼花閱讀 571評(píng)論 4 6