scala-数组与元组

数组与元组

数组定义

数组几乎是所有语言中最基础的数据结构,数组可索引、类型一致、长度不变

Scala数组分为定长数组和变长数组

  • 定长数组:Array
  • 变长数组:ArrayBuffer
package hhb.cn.part03

/**
 * @description:数组
 * 在Scala中,分为定长数组和可变数组
 * 定长数组:Array,长度是不变的
 * 变长数组:ArrayBuffer,长度是可变的
 * @author: huanghongbo
 * @date: 2020-09-23 15:09
 **/
object ArrayDemo {

  def main(args: Array[String]): Unit = {
    println("===========定长数组=============")
    //定义长度为10的整型定长数组,初始值为0
    val nums = new Array[Int](10)

    //定义长度为10的字符串型定长数组,初始值为 null
    val strs = new Array[String](10)

    //通过索引访问数组元素,索引从0开始,使用 () 而不是 []
    println(strs(0))

    //省略了关键词new,那么Scala会进行自动类型推断
    val arrays: Array[Int] = Array(1, 2, 3, 4, 5)
    val arrays2: Array[Nothing] = Array()
    println(arrays.length)

    //通过toArray快速定义数组,用于测试
    val array = (1 to 10).toArray
  }
}

变长数组

长度按需要变换的数组ArrayBuffer。Scala 中很多数组类型都有可变、不可变两个版本,推荐使用不可变的数组类型,使用可变数组类型时需要显示声明;

使用ArrayBuffer时,需要导包 import scala.collection.mutable.ArrayBuffer;

println("===========变长数组=============")
//定义一个空的Int变长数组
//注意,后面要有小括号
val arrayBuffer = ArrayBuffer[Int]()
//通过+= 在尾端添加一个或者多个元素
arrayBuffer += 1
arrayBuffer += (2, 3, 4, 5)
//通过 ++= 在尾端添加集合
arrayBuffer ++= (6 to 10).toArray
arrayBuffer.foreach(println(_))
println("========================")

// 还可通过 -= 和 --= 对变长数组进行删减
arrayBuffer -= 10
arrayBuffer --= (1 to 5).toArray
arrayBuffer.foreach(println(_))
println("========================")
//使用append 追加元素
arrayBuffer.append(1)
arrayBuffer.appendAll(Array(1, 2, 3))
arrayBuffer.foreach(println(_))

println("========================")
//使用insert 在某个索引之前插入元素
arrayBuffer.insert(0, 0)
arrayBuffer.insertAll(1, Array(8, 9, 10))
arrayBuffer.foreach(println(_))
println("========================")
//移除元素
//移除最后N个元素
arrayBuffer.trimEnd(3)
arrayBuffer.foreach(println(_))
println("========================")
//移除最开始的N个元素
arrayBuffer.trimStart(2)
arrayBuffer.foreach(println(_))
println("========================")

// 通过remove 从某个索引处移除一个或多个元素
arrayBuffer.remove(3)
arrayBuffer.remove(2, 4)
arrayBuffer.foreach(println(_))
println("========================")

数组操作

数组转换

//使用 toArray把变长数组转换成定长数组
val array1 = arrayBuffer.toArray
//使用toBuffer把定长数组转换成变长数组
val buffer = array1.toBuffer

数组遍历

//使用until进行数组遍历
for (i <- 0 until arrayBuffer.length) {
  println(arrayBuffer(i))
}
//使用to进行数组遍历
for (i <- 0 to arrayBuffer.length - 1) {
  println(arrayBuffer(i))
}
// 使用增加的for循环进行数组遍历
for (ele <- arrayBuffer) println(ele)
//使用forEach进行数组遍历
arrayBuffer.foreach(println(_))

常见算法

在Scala中对数组进行转换非常简单方便,这些转换动作不会修改原始数组,而是产生一个全新的数组。

package hhb.cn.part03

/**
 * @description:
 * @date: 2020-09-23 21:17
 **/
object OperatorDemo {
  def main(args: Array[String]): Unit = {
    //将数组中的偶数加倍,奇数丢弃
    val nums = 1 to 10
    val array1 = for (num <- nums if num % 2 == 0) yield num * 2
    val array2 = for (num <- nums) yield if (num % 2 == 0) num * 2 else 0
    array1.foreach(println(_))
    println("===================")
    array2.foreach(println(_))
    println("===================")
    //使用scala高阶函数
    nums.filter(_ % 2 == 0).map(_ * 2).foreach(println(_))
    println("===================")
    //取出数组中的第一个元素
    println(nums.head)
    //取出数组中的最后一个元素
    println(nums.end)
    //取出数组中除了第一个剩下的所有元素
    println(nums.tail.toBuffer)
    //取出数组中除了最后一个剩下的所有元素
    println(nums.init.toBuffer)

    //求和
    println(nums.sum)
    //求最大值
    println(nums.max)
    //求最小值
    println(nums.min)

    val nums2 = Array(2, 1, 4, 3)
    //排序
    println(nums2.sorted.toBuffer)
    //数组的元素相乘
    println(nums2.product)

    val nums3 = Array(2, 1, 4, 3, 1, 2, 3)
    //把数组里面的每一个元素都乘2
    println(nums3.map(_ * 2).toBuffer)
    //对数组所有的元素进行累加
    println(nums3.reduce(_ + _))
    //对数组进行去重
    println(nums3.distinct.toBuffer)
    //求数组长度
    println(nums3.length)
    println(nums3.size)
    //获取每个元素的索引
    println(nums3.indices)
    //使用mkString进行输出
    //输出元素,且元素与元素之间使用&分割
    println(nums3.mkString(" & "))
    // //输出元素,以 < 开头,以 > 结尾,且元素与元素之间使用&分割
    println(nums3.mkString("<", " & ", ">"))

    //count基数,注意:count后面必须有条件
    //统计数组中大于2的数量
    println(nums3.count(_ > 2))
    //统计数组中偶数的数量
    println(nums3.count(_ % 2 == 0))

    //filter:过滤出符合条件的参数,filterNot:过滤出不符合条件的参数
    //过滤出所有大于2的
    println(nums3.filter(_ > 2).toBuffer)
    //过滤出所有奇数
    println(nums3.filterNot(_ % 2 == 0).toBuffer)
    println("=========================")

    //提取前N个元素
    println(nums3.take(3).toBuffer)
    //提取后N个元素
    println(nums3.takeRight(4).toBuffer)
    //从左向右开始提取,提取符合条件的元素,如果条件不成立,则终止
    println(nums3.takeWhile(_ < 4).toBuffer)

    println("=========================")
    //删除前N个元素
    println(nums3.drop(3).toBuffer)
    //删除后N个元素
    println(nums3.dropRight(4).toBuffer)
    //从左向右开始删除,提取符合条件的元素,如果条件不成立,则终止
    println(nums3.dropWhile(_ < 4).toBuffer)
    println("=========================")
    //将数组分为两部分,前N个为一部分,剩下的为一部分
    val tuple = nums3.splitAt(3)
    println(tuple._1.toBuffer + ",,," + tuple._2.toBuffer)
    //将数组进行节前,以索引为2开始,到4结束,不包括第五个
    println(nums3.slice(2, 5).toBuffer)
    println("=========================")

    //对数组进行拉链操作
    val array_1 = Array("A", "B", "C")
    val array_2 = Array(1, 2, 3, 4)
    //拉链操作,当两个数组长度不一样时,截取相同长度
    val newArray: Array[(String, Int)] = array_1.zip(array_2)
    println(newArray.toBuffer)
    //拉链操作,当两个数组长度不一样时,array_1 用*填充,array_2用-1填充
    val newArray2: Array[(String, Int)] = array_1.zipAll(array_2, "*", -1)
    println(newArray2.toBuffer)

    //拉链操作,当两个数组长度不一样时,array_1 用 -1 填充,array_2用 * 填充
    val newArray3 = array_2.zipAll(array_1, "*", -1)
    println(newArray3.toBuffer)
    //用数组索引进行填充
    val newArray4 = array_1.zipWithIndex
    println(newArray4.toBuffer)
    println("=========================")
    //使用unzip进行数组拆分

    val (l1, l2) = newArray4.unzip
    println(l1.toBuffer)
    println(l2.toBuffer)

    val unzip = Array((1, "one", '1'), (2, "two", '2'), (3, "three", '3')).unzip3
    println(unzip._1.toBuffer)
    println(unzip._2.toBuffer)
    println(unzip._3.toBuffer)

    //数组的操作符: :+  +: ++
    //:+ 在数组的尾部加入元素
    //+: 在数组的头部加入元素
    //++ 拼接两个数组
    val num1 = (1 to 5).toArray
    val num2 = (6 to 9).toArray
    val num3 = num1 :+ 10
    val num4 = 10 +: num2
    val num5 = num1 ++ num2
    println(num3.toBuffer)
    println(num4.toBuffer)
    println(num5.toBuffer)
    println("=========================")
    //排序
    val numSort = Array(1, 5, 2, 6, 3, 7, 4, 9, 8)
    //升序
    println(numSort.sorted.toBuffer)
    println(numSort.sortWith(_ < _).toBuffer)
    //降序
    println(numSort.sorted.reverse.toBuffer)
    println(numSort.sortWith(_ > _).toBuffer)
  }
}

多维数组

通过Array的ofDim方法来定义一个多维的数组,多少行,多少列,都是自己说了算。

package hhb.cn.part03

/**
 * @description:
 * @date: 2020-09-23 22:35
 **/
object DimArrayDemo {

  def main(args: Array[String]): Unit = {
    //创建一个3行4列数据类型为Double的数组
    val array = Array.ofDim[Double](3, 4)
    array(1)(2) = 3.14
    for (i <- 0 to 2; j <- 0 to 3) {
      print(array(i)(j) + "\t")
      if (j == 3) println()
    }
  }
}

元组及操作

Tuple,元组。Map是键值对的集合。对偶是元组的最简单形态;元组是不同类型的值的集合,元组中的元素可以是不同的数据类型,元组在Scala中的应用非常广泛。

package hhb.cn.part03

/**
 * Tuple 元组可以存放不同数据类型的元素
 * 索引是从1开始的,而不是从0开始的
 * 元组在Scala中应用非常广泛,在Spark源码中会经常看见
 * 在Scala中已经事先定义好了22个Tuple,从Tuple1~Tuple22
 * 在Tuple22中最多只能有22个元素
 * @date: 2020-09-23 22:44
 **/
object TupleDemo {

  def main(args: Array[String]): Unit = {
    //定义一个元组
    val tuple1 = (1, 2.5, "spark", 'a', true)
    val tuple2 = (1, 2.5, "spark", 'a', true)
    println(tuple1 == tuple2)
    val tuple3 = (12, 2.5, "spark", 'a', true)
    println(tuple1 == tuple3)
    println(tuple1._3)

    val (t1, t2, t3, t4, t5), t = tuple1
    println(s"$t1  $t2  $t3  $t4  $t5")

    val (l1, _, l3, _, l5), l = tuple1
    println(s"$l1   $l3  $l5")

    //遍历
    for (ele <- tuple1.productIterator) {
      print(ele + "\t")
    }
    println()
    println("==============================")
    tuple1.productIterator.foreach(print(_))
  }
}
第三个模块错题集.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容