java scala 数组_Scala数组(三)

这篇博客介绍了Scala中的数组和ArrayBuffer的使用。包括定长数组与变长数组的创建、初始化、访问和修改元素的方法。强调了ArrayBuffer在尾部添加和移除元素的高效性,并展示了如何与Java数组进行互操作。此外,还提供了多个编程练习,涉及数组操作、遍历、转换以及算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要点先知

若长度固定,则使用Array,若长度可能 有变化则使用ArrayBuffer

提供初始值时不要使用new

用()来访问元素

用for(elem

用for(elem

Scala数据和Java数组可以互操作,用ArrayBuffer,使用scala.collection.JavaConversions中的转换函数

定长数组

val nums = new Array[Int](10) // 10个整数型的数组,所有元素初始化为0

val s = new Array[String](10) // 10个字符串类型数组,初始化为null

val s = Array("Hello", "World") // 提供初始值时不要用new

s(0) = "Goodbye"// Array("Goodbye", "World"), 使用()非[]访问元素

变长数组

import scala.collection.mutable.ArrayBuffer

val b = new ArrayBuffer[Int]() // 因为没有初始化,所以new和()可以只要一个

// 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个元素, .trimStart(N)移除开始N个元素

b.trimEnd(5) // ArrayBuffer(1, 1, 2)

在数组缓冲的尾端添加或移除元素是一个高效的操作,你也可以在任意位置添加或移除元素,但这样的操作并不那么高效,因为所有在哪个位置之后的元素都必须被平移。

// 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位置开始,移除lens个元素

b.remove(2) // ArrayBuffer(1, 1, 7, 8, 2)

b.remove(2, 3) // ArrayBuffer(1, 1)

有时需要构建一个Array, 但不知道最终要装多少个元素。在这种情况下,先构建一个数组缓冲,然后调用:

b.toArray。然过来,调用a.toBuffer可以将一个数组a转换成一个数组缓冲。

遍历数组

数组的长度:a.length

遍历数据index:0 until a.length // 0 until 3, Range(0, 1, 2)

遍历偶数index:0 until (a.length, 2)

从尾端开始遍历:(0 until a.length).reverse

数组装换

使用for(x

val a = Array(1, 2, 3, 4)

val result = for(elem

// 效果等同:val result = a.map(2 * _) // _是a中元素的迭代器

常用算法

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

多维数组

多维数组是通过数组的数组实现的,Double的二维数组类型为Array[Array[Double]]

// 构建3行4列的矩阵

val matrix = Array.ofDim[Double](3, 4) // matrix的每个元素初始化为0.0

// 元素访问:matrix(row)(col)

matrix(0)(0) = 1

不规则数组

val triangle = new Array[Array[Int]](5) // triangle的每个元素初始化为null

for(i

triangle(i) = new Array[Int](i + 1) // triangle(i)的每个元素初始化为0

}

与Java的互操作

Scala的数组是用Java数组实现的,所以可以在Scala和Java中来回传递。引入scala.collection.JavaConversions的隐式转换方法,这样在使用Scala缓冲,调用Java方法时,这些对象会被自动包装成Java列表。

在java.lang.ProcessBuilder类中有一个以List为参数的构造器。在Scala中调用它的例子:

import scala.collection.JavaConversions.bufferAsJavaList

import scala.collection.mutable.ArrayBuffer

val command = ArrayBuffer("ls", "-al", "/home/cay")

val pb = new ProcessBuilder(command) // Scala到Java的转换

Scala缓冲被包装成了一个实现了java.util.List接口的Java类对象。反过来,当Java方法返回java.util.List时,我们可以让它自动转换成一个Buffer:

import scala.collection.JavaConversions.asScalaBuffer

import scala.collection.mutable.Buffer

val cmd: Buffer[String] = pd.command() // Java到Scala的转换

// 不能使用ArrayBuffer, 因为包装起来的对象仅能保证是个Buffer

练习

1. 编写一段代码,将a设置为一个n个随机整数的数组,要求随机数介于[0, n)

import scala.util.Random

val n = 10

val a = new Array[Int](n)

for(elem

a(elem) = Random.nextInt(10)

}

2. 编写一个循环,将整数数组中相邻的数组置换。例如,Array(1, 2, 3, 4, 5)经过置换后变为Array(2, 1, 4, 3, 5)。

// 方法1

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

for(i

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

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. 重复上一个练习,不过这一次生成一个新的值交换过的数组。用for/yield

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

val result = new Array[Int](a.length)

// 先把下标置换好

val index = for(i

if(i == a.length - 1) {

i

}else if(i % 2 == 1){

i - 1

}else {

i + 1

}

}

// 把置换好的下标给到result

for(elem

result(elem) = a(index(elem))

}

4. 给定一个整数数组,产出一个新的数组,包含原数组中的所有正值,以原有顺序排列,之后的元素是原有零或负数,以原有顺序排列。

val a = Array(1, -1, -3, 5, -5, -2, 0, 7)

val result = new ArrayBuffer[Int]()

// 两种方法: 1. 找到下标,再赋值 2. 直接赋值

// 此处只展示方法2

result ++= (for(i 0) yield a(i))

result ++= (for(i

5. 如何计算Array[Double]的平均值?

import scala.util.Random

val a = (Seq.fill(5)(Random.nextDouble * 10)).toArray // 生成5个10以内的随机double数

a.sum / a.length

6. 如何重新组织Array[Int]的元素将它们以反序排列?对于ArrayBuffer[Int]你优惠怎么做呢?

// Array, ArrayBuffer的语法一样

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

val result = (for(i

// a.reverse

注:对于ArrayBuffer是否转换为Java List, 然后用Java.lang.util包的函数

7. 编写一段代码,产出数组中的所有值,去掉重复值。(提示:查看scaladoc)

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

a.distinct

**8. 重新编写3.4节结尾的示例。收集负值元素的下标,反序,去掉最后一个下标,然后对每一个下标调用a.remove(i)。比较这样做的效率和3.4节中另外两种方法的效率。

val a = ArrayBuffer(1, -1, -3, 5, -5, -2, 0, 7)

val result = (for(i

for(i

9. 创建一个由 java.util.TimeZone.getAvailableIDs返回的时区集合,判断条件是它们在美洲。去掉"America/"前缀并排序。

val sortedAmericanZone = java.util.TimeZone.getAvailableIDs.filter(_.startsWith("America")).map(_.replaceFirst("America/", "")).sorted

// Array、String通过filter和map等函数,结合起来无敌了

10. 引入 java.awt.datatransfer._ 并构建一个类型为 SystemFlavorMap 类型的对象: val flavors = SystemFlavorMap.getDefaultFlavorMap().asInstanceOf[SystemFlavorMap] 然后以 DataFlavor.imageFlavor 为参数调用 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)

参考

《快学Scala》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值