zoukankan      html  css  js  c++  java
  • Scala入门系列(三):数组

    Array

    与Java的Array类似,也是长度不可变的数组,此外,由于Scala与Java都是运行在JVM中,双方可以互相调用,因此Scala数组的底层实际上是Java数组。

    注意:访问数组中元素使用()而不是Java中的 []

    scala> val a = new Array[String](10)
    a: Array[String] = Array(null, null, null, null, null, null, null, null, null, n
    ull)
    scala> val a = new Array[Boolean](10)
    a: Array[Boolean] = Array(false, false, false, false, false, false, false, false
    , false, false)
    scala> a(0)
    res15: Boolean = false
    scala> val a = new Array[Int](10)
    a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
    scala> a(0) = 1
    


    可以直接使用Array()创建数组,元素类型自动推断(如果类型不一致则为公共父类型

    scala> val a = Array("Hello", "World")
    a: Array[String] = Array(Hello, World)
    scala> val a = Array("Sparks", 30)
    a: Array[Any] = Array(Sparks, 30)
    
    // 常见操作
    scala> val a = Array(3,4,1,2,5,3)
    a: Array[Int] = Array(3, 4, 1, 2, 5, 3)
    scala> val sum = a.sum
    sum: Int = 18
    scala> val max = a.max
    max: Int = 5
    scala> scala.util.Sorting.quickSort(a)
    scala> a
    res35: Array[Int] = Array(1, 2, 3, 3, 4, 5)
    scala> a.mkString
    res36: String = 123345
    scala> a.mkString(",")
    res37: String = 1,2,3,3,4,5
    scala> a.mkString("<",",",">")
    res38: String = <1,2,3,3,4,5>
    // Array的toString有些问题
    scala> a.toString
    res39: String = [I@ffd26d1
    scala> b.toString
    res40: String = ArrayBuffer(1, 6, 7, 8, 9, 10)
    

    ArrayBuffer

    类似于Java中的ArrayList长度可变集合类

    scala> import scala.collection.mutable.ArrayBuffer
    import scala.collection.mutable.ArrayBuffer
    scala> val b = ArrayBuffer[Int]()
    b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
    // 使用+=添加一个或者多个元素,spark源码中大量使用!!!
    scala> b += 1
    res17: b.type = ArrayBuffer(1)
    scala> b += (2,3,4,5)
    res18: b.type = ArrayBuffer(1, 2, 3, 4, 5)
    // 使用++=添加其他集合中的所有元素
    scala> b ++= Array(6, 7, 8, 9, 10)
    res19: b.type = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    // trimEnd方法可以从尾部截断指定个数的元素
    scala> b.trimEnd(5)
    scala> b
    res21: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5)
    // 使用insert()函数可以在指定位置插入一个或者多个元素,效率较低
    scala> b.insert(5,6)
    scala> b.insert(6, 7, 8, 9, 10)
    scala> b
    res24: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    // 使用remove()函数可以移除指定位置的一个或者多个元素
    scala> b.remove(1)
    res25: Int = 2
    scala> b.remove(1, 3)
    scala> b
    res27: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 6, 7, 8, 9, 10)
    // Array与ArrayBuffer互相转化
    scala> b.toArray
    res28: Array[Int] = Array(1, 6, 7, 8, 9, 10)
    scala> a.toBuffer
    res29: scala.collection.mutable.Buffer[Any] = ArrayBuffer(Sparks, 30)
    

    遍历Array和ArrayBuffer

    1. 使用until是RichInt提供的函数
      for (i <- 0 until b.length)
      print(b(i))

    2. 跳跃遍历,步进长度
      for (i <- 0 until (b.length, 2))
      print(b(i))

    3. 从尾部遍历
      for (i <- (0 until b.length).reverse)
      println(b(i))

    4. 使用“增强for循环”遍历
      for (e <- b)
      println(e)

    数组操作之数组转换

    1.使用yield

    scala> val a = Array(1,2,3,4,5)
    a: Array[Int] = Array(1, 2, 3, 4, 5)
    
    scala> val a2 = for(ele <- a) yield ele*ele
    a2: Array[Int] = Array(1, 4, 9, 16, 25)
    
    scala> val a = ArrayBuffer(1,2,3,4,5)
    a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5)
    
    scala> val a2 = for(ele <- a) yield ele*ele
    a2: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 4, 9, 16, 25)
    

    2.使用函数式编程
    _ 表示通配符

    • a.filter(_ % 2 == 0).map(2 * _) (推荐方式)
    • a.filter{ _ % 2 == 0} map {2 * _}

    实战:移除第一个负数之后的所有负数

    // 构建数组
    scala> val a = ArrayBuffer[Int]()
    a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
    scala> a += (1,2,3,4,5,-1,-3,-5,-9)
    res45: a.type = ArrayBuffer(1, 2, 3, 4, 5, -1, -3, -5, -9)
    
    // 发现第一个负数之后的负数,就进行移除,性能较差,多次移动数组
    var foundFirstNegative = false
    var index = 0
    while(index < a.length) {
      if (a(index) >= 0) {
        index += 1
      }
      else {
        if (!foundFirstNegative) {foundFirstNegative=true; index += 1}
        else { a.remove(index)}
      }
    }
    
    //检索出所有需要元素的下标,然后将所有需要的元素左移至数组左侧,删除右侧不需要的元素。
    //改良版,性能较高
    var foundFirstNegative = false
    val vaildIndex = for (i <- 0 until a.length if (!foundFirstNegative || a(i) >= 0)) yield {
      if (a(i) < 0) foundFirstNegative = true
      i
    }
    for(i <- 0 until vaildIndex.length) {a(i) = a(vaildIndex(i))}
    a.trimEnd(a.length - vaildIndex.length)
    
  • 相关阅读:
    public、private、protected继承的规则
    派生类对象的构造函数与析构函数
    类的保护成员
    派生类覆盖(修改)基类成员
    条款03:尽可能使用const
    处理类与类之间的关系
    继承派生基本概念
    条款02:尽量以const,enum,inline替换#define(宁可编译器替代预处理器)
    Redis持久化AOF和RDB对比
    Memcached取模算法
  • 原文地址:https://www.cnblogs.com/LiCheng-/p/8017460.html
Copyright © 2011-2022 走看看