本文详细介绍了Scala中的数组和ArrayBuffer的使用,包括数组的固定长度和动态扩展,ArrayBuffer的添加、修改、遍历以及常见操作如求和、查找最大值、排序等。还探讨了如何高效地处理数组转换和条件过滤问题。 摘要由CSDN通过智能技术生成
  • 固定长度使用 Array , 长度有可能变化使用 ArrayBuffer
  • 提供初始值不要使用 new
  • () 来访问数组
def main(args: Array[String]): Unit = {
    //定长数组
    val nums = new Array[Int](10)
    //添加元素
     nums(1) = 1
    //提供初始值不用new
    val nums2 = Array(1,2,3)
    //使用()访问而不是[]
    //修改数组
    nums2(1) = 6; 
    println("修改后" + nums2(1))
    /*ArrayBuffer 长度变化的数组,相当于java 的 arraylist*/
    val ab = new ArrayBuffer[Int]
    ab += 1 //在尾端添加元素 (1)
    ab += (2,3,5,6,7) //尾端添加多个元素 (1, 2, 3, 5, 6, 7)
    ab ++= Array(8,9,10) //追加任何集合 (1, 2, 3, 5, 6, 7, 8, 9, 10)
    ab.trimStart(1);ab.trimEnd(3) //删除第一个元素和最后3个元素 (2, 3, 5, 6, 7)
    ab.insert(2,4)//在索引2后面插入元素4,这样的操作并不是非常有效的,
                  //这需要扩大数组和平移元素 (2, 3, 4, 5, 6, 7)
    ab.remove(2)//删除索引2所在的元素 (2, 3, 5, 6, 7)
    ab.remove(2,3) //删除索引2及后面的2个元素(一共3个元素)(2, 3)
    /*有时候你需要一个Array,但不知道最终装多少元素,这种情况下,
    * 先构造一个ArrayBuffer
    * 当确定好最终元素后调用:ab.toArray
    * 反过来,ab.toBuffer来将数组ab转换成缓冲*/
  • for(elem <- arr) 来遍历元素
  • for(elem <- arr if ...) ... yield来将原数组转为新数组
def main(args: Array[String]): Unit = {
    //数组遍历
    val nums3 = Array(1,2,3,4,5,6,7,8)
    /*to方法生成的是一个包含起始值和结束值的闭区间  
      1 2 3 4 5 6 7 8 */
   for(num <- 0 to nums3.length - 1)  print(nums3(num)) 
    /*until方法生成的是一个包含起始值
      但不包含结束值的半开区间 1 2 3 4 5 6 7 8 */
   for(num <- 0 until nums3.length )  print(nums3(num)) 
    /*考虑步长的情况  1 3 5 7 */
   for(num <- 0 until(nums3.length,2) ) print(nums3(num)) 
    /*反转访问  8 7 6 5 4 3 2 1 */
   for(num <- ( 0 until nums3.length ).reverse) print(nums3(num)) 
   /*数组转换  这个操作会生成一个全新的数组 2 4 6 8 10 12 14 16*/
   val nums4 = for(elem <- nums3) yield 2 * elem    
   //加入一些条件 4 8 12 16
   val nums5 = for(elem <- nums3 if elem % 2 == 0) yield 2 * elem
   /*另外的写法*/
   val num6 = nums3.filter(_ %2 ==0 ).map(2 * _)
 

这些转换操作不会修改原数组,而是产生一个全新的数组。
从数组出发得到另一个数组, 从数组缓冲出发得到新的数组缓冲

一个示例:

给定一个整数的数组缓冲,我们想要移除除第一个负数之外的所有负数。传统的方法会在遇到第一个负数时置一个标记,然后移除后续出现的负数元素

def main(args: Array[String]): Unit = {
    val ab = ArrayBuffer(-3, -2, -1, 0, 1, 2, 3, 4)
    var first = true
    var n = ab.length
    var i = 0
    while (i < n) {
      if (ab(i) >= 0) {
        i += 1
      } else {
        if (first) {
          first = false
          i += 1
        } else {
          ab.remove(i)
          n -= 1

但实际上,写过算法题《移除元素》 的同学都知道,把非负数值拷贝到前端要好很多

  val ab1 =  ArrayBuffer(-3, -2, -1, 0, 1, 2, 3, 4)
  var first = true;
  //收集需要保留的下标
  val indexes = for( i <- 0 until ab1.length if first || ab1(i) >= 0) yield{
      if (ab1(i) < 0)  first = false
    //移动元素到该去的位置,并截断尾端
    for( j <- 0 until indexes.length) ab1(j) = ab1(indexes(j) )
    ab1.trimEnd(ab1.length - indexes.length)
    println(ab1)
//这是一个数组!
val indexes = for( i <- 0 until ab1.length if first || ab1(i) >= 0) yield{
      if (ab1(i) < 0)  first = false
上面的另一种写法是:
for (i <- 0 until ab1.length) {
  if (first || ab1(i) >= 0) {
    indexes += i // 将满足条件的索引添加到索引数组中
    if (ab1(i) < 0) {
      first = false // 遇到第一个负数后,将 first 设置为 false

数组其他常用方法

val num = Array(1,2,3,4,5).sum //15 对ArrayBuffer同样有效
val bf1 = ArrayBuffer(1,2,5,7,0).max // 7 Array同样有效
val bf2 = ArrayBuffer(1,2,5,7,0).min // 0
val a = ArrayBuffer(1, 2, 5, 7, 0).sorted // (0, 1, 2, 5, 7)
val b = ArrayBuffer(1, 2, 5, 7, 0).sorted.reverse // (7, 5, 2, 1, 0)
//可以对一个数组直接调用排序,数组缓冲不行
val c = Array(1,4,3,8,9)
Sorting.quickSort(c) // 1 3 4 8 9 
//mkString指定元素之间的分隔符
val str = Array("You", "I" ,"your friend steve")
println(str.mkString(" and "))
//结果: You and I and your friend steve
//还有一个重载是指定前中后缀
println(str.mkString("<", " and ", ">"))
//<You and I and your friend steve>
//count用于清点多少元素应该在用该函数后得到true
val d = Array(-1,2,-9,3,5,6)
println(d.count( _ < 0)) // 2 清点多少a的元素为正值
//append
val bbc = ArrayBuffer(1,2,3)
bbc.append(4,5)
println(bbc) // (1, 2, 3, 4, 5)
//appendAll将另一个集合中的所有元素
//添加到 ArrayBuffer 的末尾
val buffer = ArrayBuffer[Int]()
buffer.appendAll(Seq(1, 2, 3))
println(buffer) // 输出: ArrayBuffer(1, 2, 3)
本篇主要学习如何在Scala中操作数组。Java和C++程序员通常会选用数组或近似的结构(比如数组列表或向量)来收集一组元素。在Scala中,我们的选择更多,不过现在我们先假定不关心其他选择,而只是想马上开始用数组。
本篇的要点包括:
1. 若长度固定则使用Array,若长度可能有变化则使用ArrayBuffer
2. 提供初始值时不要使用new
3. 用()来访问元素
4. ...
				
Scala 数组 Scala 语言中提供的数组是用来存储固定大小的同类型元素,数组对于每一门编辑应语言来说都是重要的数据结构之一。 声明数组变量并不是声明 number0、number1、…、number99 一个个单独的变量,而是声明一个就像 numbers 这样的变量,然后使用 numbers[0]、numbers[1]、…、numbers[99] 来表示一个个单独的变量。数组中某个指定的元素是通过索引来访问的。 数组的第一个元素索引为0,最后一个元素的索引为元素总数减1。 声明数组 以下是 Scal
//创建不可变数组可以直接赋值 scala> var arr1=Array(10,20,30,40) arr1: Array[Int] = Array(10, 20, 30, 40) //创建不可变数组也可以只指定数组长度,暂时不赋值 scala> var arr=new Array[Int](10) arr: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) //创建一个长度1 1、不可变数组的定义 ①、val arr=new Array[Int](5) 定义一个长度为五的定长数组 ②、val arr= Array[Int](1,4,5,6,7)给定泛型和内容的定长数组 ③、val arr3=Array(1,3,true,"hello",3.5,2L) 不给泛型给内容的定长数组 2、可变数组的定义 前提:先导包 import scala.collection.mutable._ ①、val arr=new ArrayBuffer[Int]() new 一个Arr
CSDN-Ada助手: 非常恭喜您撰写了第11篇博客《Scala数组》!持续创作真是令人钦佩。通过您的文章,我对Scala数组有了更深入的了解。您的解释清晰明了,让我对这个主题有了更全面的认识。 在下一步的创作中,我建议您可以考虑扩展关于Scala数组的应用场景,或者深入探讨Scala数组的高级特性。通过这样的方式,您可以进一步提升读者对Scala数组的理解,并为他们提供更多实用的知识。 再次感谢您的辛勤努力,期待您未来更多精彩的博客文章! Spark从星火到燎原Ⅰ CSDN-Ada助手: 恭喜您撰写了第9篇博客!题为“Spark从星火到燎原Ⅰ”真是引人注目。您对Spark的深入研究和详细叙述使得读者们对这个话题有了更全面的了解。接下来,我期待能够看到您进一步探索Spark的系列文章,比如“Spark从星火到燎原Ⅱ”,以及深入挖掘Spark在不同领域的应用案例。希望您能够继续保持创作的热情,我们都非常期待您的下一步文章! Spark从星火到燎原Ⅱ CSDN-Ada助手: 恭喜博主在《Spark从星火到燎原Ⅱ》中的持续创作!您的努力和热情真的让这个系列变得更加精彩。阅读第10篇博客之后,我感受到了您对于Spark的深入理解和研究。我希望您能继续分享您的见解和经验,因为它们对于我们这些读者来说真的是非常有价值的。同时,如果可能的话,我期待着您能在未来的创作中给予一些实际应用的示例,这将使得读者更容易理解和应用您所讲解的概念。再次感谢您的分享,期待着您下一步的创作!