scala-筑基篇-01-List操作

[TOC]

List簡介

特性

  • 不可變
  • 遞歸結(jié)構(gòu)
  • 同構(gòu)(同質(zhì))的:元素的類型必須一致
  • 協(xié)變的:如果S是T的子類型,那么List[S]是List[T]的子類型,這點(diǎn)不同于java的泛型
  • 空列表為List[Nothing],Nil

創(chuàng)建列表

  • 所有的List都是由空列表Nil和操作符::構(gòu)造出來的,::表示從前端擴(kuò)張列表.
  • 實(shí)際上,用形如List(e1,e2,...)的方式創(chuàng)建列表在底層也是使用Nil::構(gòu)造出來的
scala> List(1,2,3)
res0: List[Int] = List(1, 2, 3)

scala> 1::Nil
res1: List[Int] = List(1)

scala> 2::res1
res2: List[Int] = List(2, 1)

scala> 3::res2
res3: List[Int] = List(3, 2, 1)

操作

list的基本操作

method DESC
head List的第一個(gè)元素
tail 除了head之外的其他元素組成的List
isEmpty List是否為空
last List的最后一個(gè)元素
init 除了last之外的其他元素組成的List
scala> val l1=List(1,2,3,4,5)
l1: List[Int] = List(1, 2, 3, 4, 5)

scala> l1.tail
res4: List[Int] = List(2, 3, 4, 5)

scala> l1.head
res5: Int = 1

scala> l1.isEmpty
res6: Boolean = false

scala> l1.init
res7: List[Int] = List(1, 2, 3, 4)

scala> l1.last
res8: Int = 5

list類的一階方法

連接

列表的鏈接操作符:::和擴(kuò)展元素操作符::一樣都是右結(jié)合的,即xs:::ys:::zs等價(jià)于xs:::(ys:::zs),不過兩個(gè)操作數(shù)都是List

scala> List(1,2,3):::List(4,5,6)
res9: List[Int] = List(1, 2, 3, 4, 5, 6)

長度

內(nèi)部定義:

  def length: Int = {
    var these = self
    var len = 0
    while (!these.isEmpty) {
      len += 1
      these = these.tail
    }
    len
  }

所以,length方法是比較費(fèi)時(shí)的

reverse

反轉(zhuǎn)list:reverse ,該方法并不是在原地修改list,因?yàn)閘ist是不可變的,所以會返回一個(gè)新的list

  • drop和take可以理解為更為廣義的tail和init操作
  • take(n)返回列表的前n個(gè)元素,if(n>list.length) return list
  • drop(n)返回除了take(n)之外的所有元素,if(n>list.length) return Nil
  • splitAt(n)在位置n處拆分列表,返回位元組。等價(jià)于(list.take(n),list.drop(n))
scala> val l1=Range(1,11).toList
l1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> l1.take(3)
res10: List[Int] = List(1, 2, 3)

scala> l1.drop(3)
res11: List[Int] = List(4, 5, 6, 7, 8, 9, 10)

scala> l1.splitAt(3)
res12: (List[Int], List[Int]) = (List(1, 2, 3),List(4, 5, 6, 7, 8, 9, 10))

apply | indices

scala> val l1=Range(1,11).toList
l1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> l1.apply(2)
res13: Int = 3

scala> l1(2)
res14: Int = 3

scala> l1.indices
res15: scala.collection.immutable.Range = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

zip

不匹配的元素將被遺棄

scala> val l1=Range(1,4).toList
l1: List[Int] = List(1, 2, 3)

scala> val l2=List("a","b","c","d")
l2: List[String] = List(a, b, c, d)

scala> l1.zip(l2)
res16: List[(Int, String)] = List((1,a), (2,b), (3,c))

mkString

mkString([start,]seperator[,end])

scala> val l=Range(1,5).toList
l: List[Int] = List(1, 2, 3, 4)

scala> l.mkString("start","|","end")
res17: String = start1|2|3|4end

scala> l.mkString("|")
res18: String = 1|2|3|4

list類的高階方法

foreach

遍歷list并將傳入的lambda作用于每個(gè)元素

內(nèi)部實(shí)現(xiàn):

  @inline final override def foreach[U](f: A => U) {
    var these = this
    while (!these.isEmpty) {
      f(these.head)
      these = these.tail
    }
  }

遍歷

val l1 = Range(1, 11).toList
l1.foreach(e => { print(e + " ") })

l1.foreach(print(_))

等價(jià)的java8操作

List<Integer> list = Stream.iterate(1, i -> i + 1).limit(10)
        .collect(Collectors.toList());
list.forEach(e -> {
    System.out.print(e + " ");
});

list.forEach(System.out::print);

求和

val l1 = Range(1, 11).toList
var sum = 0
l1.foreach(sum += _)
println(sum)

map

參數(shù)f:T=>R,將f作用于每個(gè)元素,并返回類型為R的新列表

構(gòu)造新list,元素為原list的元素的2倍

l1.map(e => e * 2)
println(l1)

等價(jià)的java8代碼

list.stream().map(e->e*2).collect(Collectors.toList());

flatMap

和map類型,但請注意返回類型

scala> val l=List("tom","cat","apache")
l: List[String] = List(tom, cat, apache)

scala> l.map(_.toList)
res19: List[List[Char]] = List(List(t, o, m), List(c, a, t), List(a, p, a, c, h, e))

scala> l.flatMap(_.toList)
res20: List[Char] = List(t, o, m, c, a, t, a, p, a, c, h, e)

filter

scala> val l=Range(1,11).toList
l: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> l.filter(e=>(e%2)==0)
res22: List[Int] = List(2, 4, 6, 8, 10)

scala> l.filter(e=>(e&1)==0)
res24: List[Int] = List(2, 4, 6, 8, 10)

partition

返回二元組(符合條件的部分,不符合條件的部分)

scala> val l=Range(1,11).toList
l: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> l.partition(e=>(e%2)==0)
res26: (List[Int], List[Int]) = (List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9))

find

返回第一個(gè)滿足條件的

scala> l.find(e=>(e%2)==0)
res27: Option[Int] = Some(2)

takeWhile | dropWhile | span

  • takeWhile(p):返回能夠滿足p的最長前綴組成的list
  • dropWhile(p):返回list中除了takeWhile(n)的部分組成的列表
  • span:類似于slitAt結(jié)合了take和drop,span結(jié)合了takeWhile和dropWhile的結(jié)果
scala> val l=List(1,2,3,-1,2,3)
l: List[Int] = List(1, 2, 3, -1, 2, 3)

scala> l.dropWhile(_>0)
res28: List[Int] = List(-1, 2, 3)

scala> l.takeWhile(_>0)
res30: List[Int] = List(1, 2, 3)

scala> l.span(_>0)
res31: (List[Int], List[Int]) = (List(1, 2, 3),List(-1, 2, 3))

論斷(forall,exists)

scala> val l=List(1,2,3,-1,2,3)
l: List[Int] = List(1, 2, 3, -1, 2, 3)

scala> l.forall(_>0)
res33: Boolean = false

scala> l.exists(_>0)
res35: Boolean = true

折疊

  • 1.foldLeft(/:)

內(nèi)部實(shí)現(xiàn):

//注意op第一個(gè)參數(shù)類型為seed的類型
  override /*TraversableLike*/
  def foldLeft[B](z: B)(@deprecatedName('f) op: (B, A) => B): B = {
    var acc = z//z表示初始值,seed
    var these = this
    while (!these.isEmpty) {
      //每次將op作用于當(dāng)前seed和當(dāng)前元素并將結(jié)果重新賦值于seed
      acc = op(acc, these.head)
      these = these.tail
    }
    //最終返回"累加"的結(jié)果
    acc
  }
  • 2.foldRight(:\)

內(nèi)部實(shí)現(xiàn):

//反轉(zhuǎn)后調(diào)用foldLeft
//注意op第二個(gè)參數(shù)類型為seed的類型
override def foldRight[B](z: B)(op: (A, B) => B): B =
  reverse.foldLeft(z)((right, left) => op(left, right))
  • 3.fold

內(nèi)部實(shí)現(xiàn):

//注意op的兩個(gè)參數(shù)類型相同
def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)

求和

val l1 = Range(1, 11).toList

var sum = l1.foldLeft(0)((acc, e) => acc + e)
println(sum) //55

sum = l1./:(0)((acc, e) => acc + e)
println(sum) //55

sum = l1.foldRight(0)((e, acc) => acc + e)
println(sum) //55

sum = l1.fold(0)((acc, e) => acc + e)
println(sum) //55

sum = l1.foldLeft(0)(_ + _)
println(sum) //55

sum = l1./:(0)(_ + _)
println(sum) //55

sum = (0 /: l1)(_ + _) //相當(dāng)于 l1./:(0)
//sum = (l1 /: 0)(_ + _) //錯(cuò)誤,相當(dāng)于0./:(l1)
println(sum) //55

乘積

var pro = 1
val l1 = Range(1, 11).toList
pro = l1.foldLeft(1)((acc, e) => acc * e)
println(pro) //3628800

pro = (1 /: l1)(_ * _)
println(pro) //3628800

排序

  • 1.sortWith(p: (Int, Int) => Boolean)
val l1 = Range(1, 11).toList

var l2 = l1.sortWith((l, r) => l > r)
println(l2) //List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

l2 = l1.sortWith(_ > _)
println(l2) //List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

list對象的方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,665評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,627評論 2 380

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