日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

scala 集合

發布時間:2025/7/25 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 scala 集合 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基本數據結構

Scala提供了一些很方便的集合類。

參考?《Effective Scala》中關于怎么使用集合類的內容。

List

1 2 scala> val numbers = List(1, 2, 3, 4) numbers: List[Int] = List(1, 2, 3, 4)

Set

集合中沒有重復元素

1 2 scala> Set(1, 1, 2) res0: scala.collection.immutable.Set[Int] = Set(1, 2)

元組(Tuple)

元組可以直接把一些具有簡單邏輯關系的一組數據組合在一起,并且不需要額外的類。

1 2 scala> val hostPort = ("localhost", 80) hostPort: (String, Int) = (localhost, 80)

和case class不同,元組的元素不能通過名稱進行訪問,不過它們可以通過基于它們位置的名稱進行訪問,這個位置是從1開始而非從0開始。

1 2 3 4 5 scala> hostPort._1 res0: String = localhost scala> hostPort._2 res1: Int = 80

元組可以很好地和模式匹配配合使用。

1 2 3 4 hostPort match { ??case ("localhost", port) => ... ??case (host, port) => ... }

創建一個包含2個值的元組有一個很簡單的方式:->

1 2 scala> 1 -> 2 res0: (Int, Int) = (1,2)

參考?《Effective Scala》中關于解除綁定(拆封一個元組)的觀點。

Map

Map里可以存放基本的數據類型。

1 2 Map(1 -> 2) Map("foo" -> "bar")

這個看起來是一個特殊的語法,不過回想一下前面我們討論元組的時候,->符號是可以用來創建元組的。

Map()可以使用我們在第一節里講到的可變參數的語法:Map( 1 -> "one", 2 -> "two"),它會被擴展為Map((1,"one"),(2,"two")),其中第一個元素參數是key,第二個元素是value。

Map里也可以包含Map,甚至也可以把函數當作值存在Map里。

1 Map(1 -> Map("foo" -> "bar"))
1 Map("timesTwo" -> { timesTwo(_) })

Option

Option是一個包含或者不包含某些事物的容器。

Option的基本接口類似于:

1 2 3 4 5 trait Option[T] { ??def isDefined: Boolean ??def get: T ??def getOrElse(t: T): T }

Option本身是泛型的,它有兩個子類:Some[T]和None

我們來看一個Option的示例:?Map.get使用Option來作為它的返回類型。Option的作用是告訴你這個方法可能不會返回你請求的值。

1 2 3 4 5 6 7 8 scala> val numbers = Map(1 -> "one", 2 -> "two") numbers: scala.collection.immutable.Map[Int,String] = Map((1,one), (2,two)) scala> numbers.get(2) res0: Option[java.lang.String] = Some(two) scala> numbers.get(3) res1: Option[java.lang.String] = None

現在,我們要的數據存在于這個Option里。那么我們該怎么處理它呢?

一個比較直觀的方法就是根據isDefined方法的返回結果作出不同的處理。

1 2 3 4 5 6 7 //如果這個值存在的話,那么我們把它乘以2,否則返回0。 val result = if (res1.isDefined) { ??res1.get * 2 } else { ??0 }

?

不過,我們更加建議你使用getOrElse或者模式匹配來處理這個結構。

getOrElse讓你可以很方便地定義一個默認值。

1 val result = res1.getOrElse(0) * 2

模式匹配可以很好地和Option進行配合使用。

val result = res1 match { case Some(n) => n * 2 case None => 0 }

參考?《Effective Scala》中關于?Options的內容。

?

函數組合器

List(1,2,3) map squared會在列表的每個元素上分別應用squared函數,并且返回一個新的列表,可能是List(1,4,9)。我們把類似于map這樣的操作稱為組合器。(如果你需要一個更好的定義,你或許會喜歡Stackoverflow上的關于組合器的解釋。

map

在列表中的每個元素上計算一個函數,并且返回一個包含相同數目元素的列表。

1 2 scala> numbers.map((i: Int) => i * 2) res0: List[Int] = List(2, 4, 6, 8)

或者傳入一個部分計算的函數

1 2 3 4 5 scala> def timesTwo(i: Int): Int = i * 2 timesTwo: (i: Int)Int scala> numbers.map(timesTwo _) res0: List[Int] = List(2, 4, 6, 8)

foreach

foreach和map相似,只不過它沒有返回值,foreach只要是為了對參數進行作用。

1 scala> numbers.foreach((i: Int) => i * 2)

沒有返回值。

你可以嘗試把返回值放在一個變量里,不過它的類型應該是Unit(或者是void)

1 2 scala> val doubled = numbers.foreach((i: Int) => i * 2) doubled: Unit = ()

filter

移除任何使得傳入的函數返回false的元素。返回Boolean類型的函數一般都稱為斷言函數。

1 2 scala> numbers.filter((i: Int) => i % 2 == 0) res0: List[Int] = List(2, 4)
1 2 3 4 5 scala> def isEven(i: Int): Boolean = i % 2 == 0 isEven: (i: Int)Boolean scala> numbers.filter(isEven _) res2: List[Int] = List(2, 4)

zip

zip把兩個列表的元素合成一個由元素對組成的列表里。

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

partition

partition根據斷言函數的返回值對列表進行拆分。

1 2 3 scala> val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) scala> numbers.partition(_ %2 == 0) res0: (List[Int], List[Int]) = (List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9))

find

find返回集合里第一個匹配斷言函數的元素

1 2 scala> numbers.find((i: Int) => i > 5) res0: Option[Int] = Some(6)

drop & dropWhile

drop丟棄前i個元素

1 2 scala> numbers.drop(5) res0: List[Int] = List(6, 7, 8, 9, 10)

dropWhile移除前幾個匹配斷言函數的元素。例如,如果我們從numbers列表里dropWhile奇數的話,1會被移除(3則不會,因為它被2所“保護”)。

1 2 scala> numbers.dropWhile(_ % 2 != 0) res0: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)

foldLeft

1 2 scala> numbers.foldLeft(0)((m: Int, n: Int) => m + n) res0: Int = 55

0是起始值(注意numbers是一個List[Int]),m是累加值。

更加直觀的來看:

1 2 3 4 5 6 7 8 9 10 11 12 scala> numbers.foldLeft(0) { (m: Int, n: Int) => println("m: " + m + " n: " + n); m + n } m: 0 n: 1 m: 1 n: 2 m: 3 n: 3 m: 6 n: 4 m: 10 n: 5 m: 15 n: 6 m: 21 n: 7 m: 28 n: 8 m: 36 n: 9 m: 45 n: 10 res0: Int = 55

foldRight

這個和foldLeft相似,只不過是方向相反。

1 2 3 4 5 6 7 8 9 10 11 12 scala> numbers.foldRight(0) { (m: Int, n: Int) => println("m: " + m + " n: " + n); m + n } m: 10 n: 0 m: 9 n: 10 m: 8 n: 19 m: 7 n: 27 m: 6 n: 34 m: 5 n: 40 m: 4 n: 45 m: 3 n: 49 m: 2 n: 52 m: 1 n: 54 res0: Int = 55

flatten

flatten可以把嵌套的結構展開。

1 2 scala> List(List(1, 2), List(3, 4)).flatten res0: List[Int] = List(1, 2, 3, 4)

flaoMap

flatMap是一個常用的combinator,它結合了map和flatten的功能。flatMap接收一個可以處理嵌套列表的函數,然后把返回結果連接起來。

1 2 3 4 5 scala> val nestedNumbers = List(List(1, 2), List(3, 4)) nestedNumbers: List[List[Int]] = List(List(1, 2), List(3, 4)) scala> nestedNumbers.flatMap(x => x.map(_ * 2)) res0: List[Int] = List(2, 4, 6, 8)

可以把它當作map和flatten兩者的縮寫:

1 2 scala> nestedNumbers.map((x: List[Int]) => x.map(_ * 2)).flatten res1: List[Int] = List(2, 4, 6, 8)

這個調用map和flatten的示例是這些函數的類“組合器”特點的展示。

See Also?Effective Scala has opinions about?flatMap.

參考?《Effective Scala》中關于flatMap的內容.

廣義的函數組合器

現在,我們學習了一大堆處理集合的函數。

不過,我們更加感興趣的是怎么寫我們自己的函數組合器。

有趣的是,上面展示的每個函數組合器都是可以通過fold來實現的。我們來看一些示例。

1 2 3 4 5 6 7 8 def ourMap(numbers: List[Int], fn: Int => Int): List[Int] = { ??numbers.foldRight(List[Int]()) { (x: Int, xs: List[Int]) => ????fn(x) :: xs ??} } scala> ourMap(numbers, timesTwo(_)) res0: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

為什么要List[Int]?因為Scala還不能聰明到知道你需要在一個空的Int列表上來進行累加。

如何處理好Map?

我們上面所展示的所有函數組合器都能都Map進行處理。Map可以當作是由鍵值對組成的列表,這樣你寫的函數就可以對Map里的key和value進行處理。

1 2 scala> val extensions = Map("steve" -> 100, "bob" -> 101, "joe" -> 201) extensions: scala.collection.immutable.Map[String,Int] = Map((steve,100), (bob,101), (joe,201))

現在過濾出所有分機號碼小于200的元素。

1 2 scala> extensions.filter((namePhone: (String, Int)) => namePhone._2 < 200) res0: scala.collection.immutable.Map[String,Int] = Map((steve,100), (bob,101))

?

因為你拿到的是一個元組,所以你不得不通過它們的位置來取得對應的key和value,太惡心了!

幸運的是,我們實際上可以用一個模式匹配來優雅地獲取key和value。

1 2 scala> extensions.filter({case (name, extension) => extension < 200}) res0: scala.collection.immutable.Map[String,Int] = Map((steve,100), (bob,101))

為什么這樣也可以呢?為什么可以直接傳入一個局部的模式匹配呢?

這個內容就留在下周吧!

英文原文:?Scala School,翻譯:ImportNew?–?朱偉杰

本文鏈接:http://www.importnew.com/3673.html

總結

以上是生活随笔為你收集整理的scala 集合的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。