Scala數(shù)組(三)

要點(diǎn)先知

  • 若長(zhǎng)度固定湖笨,則使用Array辛润,若長(zhǎng)度可能 有變化則使用ArrayBuffer
  • 提供初始值時(shí)不要使用new
  • ()來(lái)訪問(wèn)元素
  • for(elem <- arr)來(lái)遍歷元素
  • for(elem <- arr if ...)...yeild...來(lái)將原數(shù)組轉(zhuǎn)型為新數(shù)組
  • Scala數(shù)據(jù)和Java數(shù)組可以互操作,用ArrayBuffer怒允,使用scala.collection.JavaConversions中的轉(zhuǎn)換函數(shù)

定長(zhǎng)數(shù)組

val nums = new Array[Int](10) // 10個(gè)整數(shù)型的數(shù)組砰嘁,所有元素初始化為0
val s = new Array[String](10) // 10個(gè)字符串類型數(shù)組,初始化為null
val s = Array("Hello", "World") // 提供初始值時(shí)不要用new
s(0) = "Goodbye"http:// Array("Goodbye", "World"), 使用()非[]訪問(wèn)元素

變長(zhǎng)數(shù)組

import scala.collection.mutable.ArrayBuffer
val b = new ArrayBuffer[Int]() // 因?yàn)闆](méi)有初始化市殷,所以new和()可以只要一個(gè)
// val b =  ArrayBuffer[Int]() or val b = new ArrayBuffer[Int]

// 用+=給b尾端添加元素
b += 1 // ArrayBuffer(1)
b += (1, 2, 3, 5) // ArrayBuffer(1, 1, 2, 3, 5)
// 用++=追加任何集合
b ++= Array(8, 13, 21) // ArrayBuffer(1, 1, 2, 3, 5, 8, 13, 21)
// 用.trimEnd(N) 移除最后N個(gè)元素, .trimStart(N)移除開(kāi)始N個(gè)元素
b.trimEnd(5) // ArrayBuffer(1, 1, 2)

在數(shù)組緩沖的尾端添加或移除元素是一個(gè)高效的操作愕撰,你也可以在任意位置添加或移除元素,但這樣的操作并不那么高效醋寝,因?yàn)樗性谀膫€(gè)位置之后的元素都必須被平移搞挣。

// b.insert(pos, nums), 在pos位置之前插入nums
b.insert(2, 6, 7, 8) // ArrayBuffer(1, 1, 6, 7, 8, 2)
// b.remove(pos, lens = 1), 從pos位置開(kāi)始,移除lens個(gè)元素
b.remove(2) // ArrayBuffer(1, 1, 7, 8, 2)
b.remove(2, 3) // ArrayBuffer(1, 1)

有時(shí)需要構(gòu)建一個(gè)Array, 但不知道最終要裝多少個(gè)元素音羞。在這種情況下囱桨,先構(gòu)建一個(gè)數(shù)組緩沖,然后調(diào)用:
b.toArray嗅绰。然過(guò)來(lái)舍肠,調(diào)用a.toBuffer可以將一個(gè)數(shù)組a轉(zhuǎn)換成一個(gè)數(shù)組緩沖搀继。

遍歷數(shù)組

  • 數(shù)組的長(zhǎng)度:a.length
  • 遍歷數(shù)據(jù)index:0 until a.length // 0 until 3, Range(0, 1, 2)
  • 遍歷偶數(shù)index:0 until (a.length, 2)
  • 從尾端開(kāi)始遍歷:(0 until a.length).reverse

數(shù)組裝換

使用for(x <- arr)yield func(x) 可以把a(bǔ)rr數(shù)組做map函數(shù)轉(zhuǎn)換

val a = Array(1, 2, 3, 4)
val result = for(elem <- a) yield 2 * elem // result = Array(2, 4, 6, 8)
// 效果等同:val result = a.map(2 * _) // _是a中元素的迭代器

常用算法

可以在Scala API文檔查看Array和ArrayBuffer的常用方法

多維數(shù)組

多維數(shù)組是通過(guò)數(shù)組的數(shù)組實(shí)現(xiàn)的,Double的二維數(shù)組類型為Array[Array[Double]]

// 構(gòu)建3行4列的矩陣
val matrix = Array.ofDim[Double](3, 4) // matrix的每個(gè)元素初始化為0.0
// 元素訪問(wèn):matrix(row)(col)
matrix(0)(0) = 1

不規(guī)則數(shù)組

val triangle = new Array[Array[Int]](5) // triangle的每個(gè)元素初始化為null
for(i <- 0 until triangle.length){
    triangle(i) = new Array[Int](i + 1) // triangle(i)的每個(gè)元素初始化為0
}

與Java的互操作

Scala的數(shù)組是用Java數(shù)組實(shí)現(xiàn)的翠语,所以可以在Scala和Java中來(lái)回傳遞叽躯。引入scala.collection.JavaConversions的隱式轉(zhuǎn)換方法,這樣在使用Scala緩沖肌括,調(diào)用Java方法時(shí)点骑,這些對(duì)象會(huì)被自動(dòng)包裝成Java列表。

java.lang.ProcessBuilder類中有一個(gè)以List<String>為參數(shù)的構(gòu)造器谍夭。在Scala中調(diào)用它的例子:

import scala.collection.JavaConversions.bufferAsJavaList
import scala.collection.mutable.ArrayBuffer
val command = ArrayBuffer("ls", "-al", "/home/cay")
val pb = new ProcessBuilder(command) // Scala到Java的轉(zhuǎn)換

Scala緩沖被包裝成了一個(gè)實(shí)現(xiàn)了java.util.List接口的Java類對(duì)象黑滴。反過(guò)來(lái),當(dāng)Java方法返回java.util.List時(shí)慧库,我們可以讓它自動(dòng)轉(zhuǎn)換成一個(gè)Buffer

import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable.Buffer
val cmd: Buffer[String] = pd.command() // Java到Scala的轉(zhuǎn)換
// 不能使用ArrayBuffer, 因?yàn)榘b起來(lái)的對(duì)象僅能保證是個(gè)Buffer

練習(xí)

1. 編寫一段代碼跷跪,將a設(shè)置為一個(gè)n個(gè)隨機(jī)整數(shù)的數(shù)組,要求隨機(jī)數(shù)介于[0, n)

import scala.util.Random
val n = 10
val a = new Array[Int](n)
for(elem <- 0 until n){
    a(elem) = Random.nextInt(10)
}

2. 編寫一個(gè)循環(huán)齐板,將整數(shù)數(shù)組中相鄰的數(shù)組置換吵瞻。例如,Array(1, 2, 3, 4, 5)經(jīng)過(guò)置換后變?yōu)锳rray(2, 1, 4, 3, 5)甘磨。

// 方法1
val a = Array(1, 2, 3, 4, 5)
for(i <- 0 until (a.length - 2, 2)){
    val t = a(i)
    a(i) = a(i + 1)
    a(i + 1) = t

}
// 方法2
val a = Array(1, 2, 3, 4, 5)
val result = new Array[Int](a.length)
for(i <- 0 until a.length){
    if(i == a.length - 1) {
        result(i) = a(i)
        }else if(i % 2 == 1){
            result(i) = a(i - 1)
            }else {
                result(i) = a(i + 1)
            }
}

3. 重復(fù)上一個(gè)練習(xí)橡羞,不過(guò)這一次生成一個(gè)新的值交換過(guò)的數(shù)組。用for/yield

val a = Array(1, 2, 3, 4, 5)
val result = new Array[Int](a.length)
// 先把下標(biāo)置換好
val index = for(i <- 0 until a.length) yield {
     if(i == a.length - 1) {
       i
        }else if(i % 2 == 1){
            i - 1
            }else {
                i + 1
            }
        }
// 把置換好的下標(biāo)給到result  
for(elem <- 0 until result.length){
    result(elem) = a(index(elem))
}

4. 給定一個(gè)整數(shù)數(shù)組济舆,產(chǎn)出一個(gè)新的數(shù)組卿泽,包含原數(shù)組中的所有正值,以原有順序排列滋觉,之后的元素是原有零或負(fù)數(shù)签夭,以原有順序排列。

val a = Array(1, -1, -3, 5, -5, -2, 0, 7)
val result = new ArrayBuffer[Int]()
// 兩種方法: 1. 找到下標(biāo)椎侠,再賦值 2. 直接賦值
// 此處只展示方法2
result ++= (for(i <- 0 until a.length if a(i) > 0) yield a(i))
result ++= (for(i <- 0 until a.length if a(i) <= 0) yield a(i))

5. 如何計(jì)算Array[Double]的平均值第租?

import scala.util.Random
val a = (Seq.fill(5)(Random.nextDouble * 10)).toArray // 生成5個(gè)10以內(nèi)的隨機(jī)double數(shù)
a.sum / a.length

6. 如何重新組織Array[Int]的元素將它們以反序排列?對(duì)于ArrayBuffer[Int]你優(yōu)惠怎么做呢我纪?

// Array, ArrayBuffer的語(yǔ)法一樣
val a = Array(1, 2, 3, 4, 5)
val result = (for(i <- (0 until a.length).reverse) yield a(i)) // 返回的是Vector類型
// a.reverse

注:對(duì)于ArrayBuffer是否轉(zhuǎn)換為Java List, 然后用Java.lang.util包的函數(shù)

7. 編寫一段代碼慎宾,產(chǎn)出數(shù)組中的所有值,去掉重復(fù)值。(提示:查看scaladoc)

val a = Array(1, 2, 3, 4, 5, 1, 1, 2, 3, 4)
a.distinct

**8. 重新編寫3.4節(jié)結(jié)尾的示例浅悉。收集負(fù)值元素的下標(biāo)趟据,反序,去掉最后一個(gè)下標(biāo)术健,然后對(duì)每一個(gè)下標(biāo)調(diào)用a.remove(i)汹碱。比較這樣做的效率和3.4節(jié)中另外兩種方法的效率。

val a = ArrayBuffer(1, -1, -3, 5, -5, -2, 0, 7)
val result = (for(i <- 0 until a.length if a(i) < 0) yield i).reverse.dropRight(1)
for(i <- result) a.remove(i)

9. 創(chuàng)建一個(gè)由 java.util.TimeZone.getAvailableIDs返回的時(shí)區(qū)集合荞估,判斷條件是它們?cè)诿乐蘅却佟Hサ?America/"前綴并排序色难。

val sortedAmericanZone = java.util.TimeZone.getAvailableIDs.filter(_.startsWith("America")).map(_.replaceFirst("America/", "")).sorted
// Array、String通過(guò)filter和map等函數(shù)等缀,結(jié)合起來(lái)無(wú)敵了

10. 引入 java.awt.datatransfer._ 并構(gòu)建一個(gè)類型為 SystemFlavorMap 類型的對(duì)象: val flavors = SystemFlavorMap.getDefaultFlavorMap().asInstanceOf[SystemFlavorMap] 然后以 DataFlavor.imageFlavor 為參數(shù)調(diào)用 getNativesForFlavor 方法,以 Scala 緩沖保存返回值娇昙。

import java.awt.datatransfer._
import scala.collection.JavaConversions._
import scala.collection.mutable.Buffer
val flavors = SystemFlavorMap.getDefaultFlavorMap().asInstanceOf[SystemFlavorMap]
val flavor: Buffer[String] = flavors.getNativesForFlavor(DataFlavor.imageFlavor)

參考

  1. 《快學(xué)Scala》
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尺迂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子冒掌,更是在濱河造成了極大的恐慌噪裕,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件股毫,死亡現(xiàn)場(chǎng)離奇詭異膳音,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)铃诬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門祭陷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人趣席,你說(shuō)我怎么就攤上這事兵志。” “怎么了宣肚?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵想罕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我霉涨,道長(zhǎng)按价,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任笙瑟,我火速辦了婚禮楼镐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逮走。我一直安慰自己揍堕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布街佑。 她就那樣靜靜地躺著似踱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪墓臭。 梳的紋絲不亂的頭發(fā)上蘸鲸,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音窿锉,去河邊找鬼酌摇。 笑死膝舅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的窑多。 我是一名探鬼主播仍稀,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼埂息!你這毒婦竟也來(lái)了技潘?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤千康,失蹤者是張志新(化名)和其女友劉穎享幽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體拾弃,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡值桩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了豪椿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奔坟。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖砂碉,靈堂內(nèi)的尸體忽然破棺而出蛀蜜,到底是詐尸還是另有隱情,我是刑警寧澤增蹭,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布滴某,位于F島的核電站,受9級(jí)特大地震影響滋迈,放射性物質(zhì)發(fā)生泄漏霎奢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一饼灿、第九天 我趴在偏房一處隱蔽的房頂上張望幕侠。 院中可真熱鬧,春花似錦碍彭、人聲如沸晤硕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舞箍。三九已至,卻和暖如春皆疹,著一層夾襖步出監(jiān)牢的瞬間疏橄,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捎迫,地道東北人晃酒。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像窄绒,于是被迫代替她去往敵國(guó)和親贝次。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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

  • Array //聲明變量arr為Array整數(shù)類型的數(shù)組,包含5個(gè)元素折汞。 scala>valarr=newArra...
    flyskyzyl閱讀 5,676評(píng)論 0 4
  • 數(shù)組 :new Array[Int](8)與Array[Int](8)的區(qū)別:第一種8個(gè)元素倔幼,第二個(gè)定義一個(gè)值為8...
    夙夜M閱讀 1,779評(píng)論 1 2
  • 數(shù)組是一種可變的、可索引的數(shù)據(jù)集合爽待。在Scala中用Array[T]的形式來(lái)表示Java中的數(shù)組形式 T[]损同。 v...
    時(shí)待吾閱讀 956評(píng)論 0 0
  • Overview 本節(jié)主要介紹幾種語(yǔ)言中的數(shù)組和集合的對(duì)應(yīng)用法。 數(shù)組在程序中一般用于表示一段連續(xù)的空間鸟款。通常來(lái)說(shuō)...
    bookislife閱讀 957評(píng)論 0 0
  • Scala的集合類可以從三個(gè)維度進(jìn)行切分: 可變與不可變集合(Immutable and mutable coll...
    時(shí)待吾閱讀 5,826評(píng)論 0 4