Scala入门到精通——第三节 Array、List

2023-10-27

本节主要内容
数组操作实战
列表List操作实战
数组操作实战
1 定长数组

//定义一个长度为10的数值数组
scala> val numberArray=new Array[Int](10)
numberArray: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
//定义一个长度为10的String类型数组
scala> val strArray=new Array[String](10)
strArray: Array[String] = Array(null, null, null, null, null, null, null, null,
null, null)

//可以看出:复杂对象类型在数组定义时被初始化为null,数值型被初始化为0

//数组元素赋值
scala> strArray(0)="First Element"
//需要注意的是,val strArray=new Array[String](10)
//这意味着strArray不能被改变,但数组内容是可以改变的
scala> strArray
res62: Array[String] = Array(First Element, null, null, null, null, null, null,
null, null, null)


//另一种定长数组定义方式
//这种调用方式其实是调用其apply方法进行数组创建操作
scala> val strArray2=Array("First","Second")
strArray2: Array[String] = Array(First, Second)

Scala中的Array以Java中的Array方式实现

2 变长数组 ArrayBuffer

//要使用ArrayBuffer,先要引入scala.collection.mutable.ArrayBuffer
scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer

//创建String类型ArrayBuffer数组缓冲
scala> val strArrayVar=ArrayBuffer[String]()
strArrayVar: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer()

//+=意思是在尾部添加元素
scala>     strArrayVar+="Hello"
res63: strArrayVar.type = ArrayBuffer(Hello)

//+=后面还可以跟多个元素的集合
//注意操作后的返回值
scala> strArrayVar+=("World","Programmer")
res64: strArrayVar.type = ArrayBuffer(Hello, World, Programmer)

//显示完整数组内容
scala> strArrayVar
res65: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(Hello, World,
Programmer)

//++=用于向数组中追加内容,++=右侧可以是任何集合
//追加Array数组
scala> strArrayVar++=Array("Wllcome","To","XueTuWuYou")
res66: strArrayVar.type = ArrayBuffer(Hello, World, Programmer, Wllcome, To, Xue
TuWuYou)
//追加List
scala> strArrayVar++=List("Wellcome","To","XueTuWuYou")
res67: strArrayVar.type = ArrayBuffer(Hello, World, Programmer, Wllcome, To, Xue
TuWuYou, Wellcome, To, XueTuWuYou)

//删除末尾n个元素
scala> strArrayVar.trimEnd(3)

scala> strArrayVar
res69: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(Hello, World,
Programmer, Wllcome, To, XueTuWuYou)
//创建整型数组缓冲
scala> var intArrayVar=ArrayBuffer(1,1,2)
intArrayVar: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 1, 2)

//在数组索引为0的位置插入元素6
scala> intArrayVar.insert(0,6)

scala> intArrayVar
res72: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(6, 1, 1, 2)

//在数组索引为0的位置插入元素7,8,9
scala> intArrayVar.insert(0,7,8,9)

scala> intArrayVar
res74: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(7, 8, 9, 6, 1, 1,2)

//从索引0开始,删除4个元素
scala> intArrayVar.remove(0,4)

scala> intArrayVar
res77: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 1, 2)

//转成定长数组
scala> intArrayVar.toArray
res78: Array[Int] = Array(1, 1, 2)

//将定长数组转成ArrayBuffer
scala> res78.toBuffer
res80: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 1, 2)

3 数组的遍历

//to
scala> for(i <- 0 to intArrayVar.length-1) println("Array Element: " +intArrayVar(i))
Array Element: 1
Array Element: 1
Array Element: 2
//until
scala> for(i <- 0 until intArrayVar.length) println("Array Element: " +intArrayVar(i))
Array Element: 1
Array Element: 1
Array Element: 2

//数组方式(推荐使用)
scala> for(i <- intArrayVar) println("Array Element: " + i)
Array Element: 1
Array Element: 1
Array Element: 2

//步长为2
scala>  for(i <- 0 until (intArrayVar.length,2)) println("Array Element: " +intA
rrayVar(i))
Array Element: 1
Array Element: 2

//倒序输出
scala> for( i<- (0 until intArrayVar.length).reverse) println("Array Element: "+
 intArrayVar(i))
Array Element: 2
Array Element: 1
Array Element: 1

4 数组转换

//生成新的数组,原数组不变
//缓冲数据转换后产生的仍然是缓冲数组
scala> var intArrayVar2=for(i <- intArrayVar) yield i*2
intArrayVar2: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 2, 4)

//定长数组转转后产生的仍然是定长数组,原数组不变
scala> var intArrayNoBuffer=Array(1,2,3)
intArrayNoBuffer: Array[Int] = Array(1, 2, 3)

scala> var intArrayNoBuffer2=for(i <- intArrayNoBuffer) yield i*2
intArrayNoBuffer2: Array[Int] = Array(2, 4, 6)

//加入过滤条件
scala>  var intArrayNoBuffer2=for(i <- intArrayNoBuffer if i>=2) yield i*2
intArrayNoBuffer2: Array[Int] = Array(4, 6)

5 数组操作中的常用算法

//定义一个整型数组
scala> val intArr=Array(1,2,3,4,5,6,7,8,9,10)
intArr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

//求和
scala> intArr.sum
res87: Int = 55

//求最大值
scala> intArr.max
res88: Int = 10

scala> ArrayBuffer("Hello","Hell","Hey","Happy").max
res90: String = Hey

//求最小值
scala> intArr.min
res89: Int = 1

//toString()方法
scala> intArr.toString()
res94: String = [I@141aba8

//mkString()方法
scala> intArr.mkString(",")
res96: String = 1,2,3,4,5,6,7,8,9,10

scala> intArr.mkString("<",",",">")
res97: String = <1,2,3,4,5,6,7,8,9,10>

6 ArrayBuffer Scaladoc解析

初学者在查看sacaladoc时常常会感到困惑,不用担心,随着学习的深入,api文档中的内容将逐渐清晰
下面给出两个示例:
++=方法传入的参数类型是TraversableOnce Trait的子类,它返回的是更新好的ArrayBuffer

这里写图片描述

7 多维数组

通过数组的数组实现多维数组的定义:

//定义2行3列数组
scala> var multiDimArr=Array(Array(1,2,3),Array(2,3,4))
multiDimArr: Array[Array[Int]] = Array(Array(1, 2, 3), Array(2, 3, 4))

//获取第一行第三列元素
scala> multiDimArr(0)(2)
res99: Int = 3

//多维数组的遍历
scala> for(i <- multiDimArr) println( i.mkString(","))
1,2,3
2,3,4

列表List操作实战
1 List类型定义及List的特点

//字符串类型List
scala> val fruit=List("Apple","Banana","Orange")
fruit: List[String] = List(Apple, Banana, Orange)

//前一个语句与下面语句等同
scala> val fruit=List.apply("Apple","Banana","Orange")
fruit: List[String] = List(Apple, Banana, Orange)

//数值类型List
scala> val nums=List(1,2,3,4,5)
nums: List[Int] = List(1, 2, 3, 4, 5)

//多重ListList的子元素为List
scala> val diagMatrix=List(List(1,0,0),List(0,1,0),List(0,0,1))
diagMatrix: List[List[Int]] = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1))

//遍历List
scala> for (i <- nums) println("List Element: "+i)
List Element: 1
List Element: 2
List Element: 3
List Element: 4
List Element: 5

不难看出,List与Array有着诸多的相似之处,但它们有两个明显的区别:
1 List一但创建,其值不能被改变
如前面的nums,改变其值的话,编译器会报错

scala> nums(3)=4
<console>:10: error: value update is not a member of List[Int]
              nums(3)=4
              ^

2 List具有递归结构(Recursive Structure),例如链表结构

List类型和其它类型集合一样,它具有协变性(Covariant),即对于类型S和T,如果S是T的子类型,则List[S]也是List[T]的子类型

例如

scala> var listStr:List[Object]=List("This","Is","Covariant","Example")
listStr: List[Object] = List(This, Is, Covariant, Example)

//空的List,其类型为Nothing,Nothing在Scala的继承层次中的最低层
//,即Nothing是任何Scala其它类型如String,Object等的子类
scala> var listStr=List()
listStr: List[Nothing] = List()

scala> var listStr:List[String]=List()
listStr: List[String] = List()

2 List常用构造方法

//采用::及Nil进行列表构建
scala> val nums = 1 :: (2 :: (3 :: (4 :: Nil)))
nums: List[Int] = List(1, 2, 3, 4)

//由于::操作符的优先级是从右往左的,因此上一条语句等同于下面这条语句
scala> val nums=1::2::3::4::Nil
nums: List[Int] = List(1, 2, 3, 4)

3 List常用操作

//判断是否为空
scala> nums.isEmpty
res108: Boolean = false

//取第一个无素
scala> nums.head
res109: Int = 1

//取除第一个元素外剩余的元素,返回的是列表
scala> nums.tail
res114: List[Int] = List(2, 3, 4)

//取列表第二个元素
scala> nums.tail.head
res115: Int = 2

//插入排序算法实现
def isort(xs: List[Int]): List[Int] =
if (xs.isEmpty) Nil
else insert(xs.head, isort(xs.tail))

def insert(x: Int, xs: List[Int]): List[Int] =
if (xs.isEmpty || x <= xs.head) x :: xs
else xs.head :: insert(x, xs.tail)

//List连接操作
scala> List(1,2,3):::List(4,5,6)
res116: List[Int] = List(1, 2, 3, 4, 5, 6)

//取除最后一个元素外的元素,返回的是列表
scala> nums.init
res117: List[Int] = List(1, 2, 3)

//取列表最后一个元素
scala> nums.last
res118: Int = 4

//列表元素倒置
scala> nums.reverse
res119: List[Int] = List(4, 3, 2, 1)

//一些好玩的方法调用
scala> nums.reverse.reverse==nums
res120: Boolean = true

scala> nums.reverse.init
res121: List[Int] = List(4, 3, 2)

scala> nums.tail.reverse
res122: List[Int] = List(4, 3, 2)

//丢弃前n个元素
scala> nums drop 3
res123: List[Int] = List(4)

scala> nums drop 1
res124: List[Int] = List(2, 3, 4)

//获取前n个元素
scala> nums take 1
res125: List[Int] = List(1)

scala> nums.take(3)
res126: List[Int] = List(1, 2, 3)

//将列表进行分割
scala> nums.splitAt(2)
res127: (List[Int], List[Int]) = (List(1, 2),List(3, 4))

//前一个操作与下列语句等同
scala> (nums.take(2),nums.drop(2))
res128: (List[Int], List[Int]) = (List(1, 2),List(3, 4))

//Zip操作
scala> val nums=List(1,2,3,4)
nums: List[Int] = List(1, 2, 3, 4)

scala> val chars=List('1','2','3','4')
chars: List[Char] = List(1, 2, 3, 4)

//返回的是List类型的元组(Tuple)
scala> nums zip chars
res130: List[(Int, Char)] = List((1,1), (2,2), (3,3), (4,4))

//List toString方法
scala> nums.toString
res131: String = List(1, 2, 3, 4)

//List mkString方法
scala> nums.mkString
res132: String = 1234

//转换成数组
scala> nums.toArray
res134: Array[Int] = Array(1, 2, 3, 4)

List伴生对象方法

//apply方法
scala>  List.apply(1, 2, 3)
res139: List[Int] = List(1, 2, 3)

//range方法,构建某一值范围内的List
scala>  List.range(2, 6)
res140: List[Int] = List(2, 3, 4, 5)

//步长为2
scala>  List.range(2, 6,2)
res141: List[Int] = List(2, 4)

//步长为-1
scala>  List.range(2, 6,-1)
res142: List[Int] = List()

scala>  List.range(6,2 ,-1)
res143: List[Int] = List(6, 5, 4, 3)

//构建相同元素的List
scala> List.make(5, "hey")
res144: List[String] = List(hey, hey, hey, hey, hey)

//unzip方法
scala> List.unzip(res145)
res146: (List[Int], List[Char]) = (List(1, 2, 3, 4),List(1, 2, 3, 4))

//list.flatten,将列表平滑成第一个无素
scala> val xss =
     | List(List('a', 'b'), List('c'), List('d', 'e'))
xss: List[List[Char]] = List(List(a, b), List(c), List(d, e))
scala> xss.flatten
res147: List[Char] = List(a, b, c, d, e)

//列表连接
scala> List.concat(List('a', 'b'), List('c'))
res148: List[Char] = List(a
, b, c)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala入门到精通——第三节 Array、List 的相关文章

  • 【机器学习】Numpy手写机器学习算法,3万行代码!

    目录 Numpy手写机器学习算法 一 前言 二 作者简介 三 项目总体介绍 四 手写 NumPy 全家福 五 项目示例 一 前言 NumPy 作为 Python 生态中最受欢迎的科学计算包 很多读者已经非常熟悉它了 它为 Python 提供
  • vue中props数据变化的问题

    发现问题 在vue项目中 父子组件数据传递是最常见的场景 但是今天在开发过程中父级数据传递到子组件 控制子组件的显隐 发现存在问题 一直监听不到数据的变化 详细排查后发现是因为props在传递数据的时候子组件接收到数据后没有及时发生变化导致
  • FatFs文件系统模块的STM32移植操作(基于STM32的SD卡官方例程说明)

    由于想要读取 MP3 文件 故学习一下 FatFs 文件系统 文章介绍了 FatFs 的移植 对移植代码进行了分析 SD卡接口函数还需参照 STM32关于SDIO的控制 控制SD卡 喜暖知寒的博客 CSDN博客 STM32对SD卡的读 写
  • J2ME平台A-RPG游戏怪物寻路算法初探

    最近似乎在手机上A RPG游戏很受欢迎 当然 我最近也在帮公司写一款A RPG类的游戏 以前从没写过这样的游戏 从有到无的写出来了 也碰到不少问题 包括屏幕滚动时地图title数组索引的校验 整个游戏框架的搭建 地图数据的处理 分层的处理
  • webpack5 笔记三,管理输出

    效果 我们在页面上添加一个按钮 点击时会打印 good morning export function sayHi console log good morning how are you const btn document create
  • [云原生专题-64]:核心概念 - 云原生技术助力5G RAN步入”云”霄 - 对云原生的理解

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122751639 目录 一 在后5G时
  • 查看IIS日志以及网站对应的IIS日志文件夹

    1 为什么要查看IIS日志 有时 我们在部署了一个程序之后 虽然程序里面记载了log日志 但有些类似503这样的错误在程序里面是无法记载的 所以我们需要通过查看IIS日志来查找问题 2 IIS日志目录 点进去之后 我们发现 IIS日志文件夹
  • JETBRAIN系列IDE改变终端的字体

    简介 JetBrains是一家捷克的软件开发公司 该公司位于捷克的布拉格 并在俄国的圣彼得堡及美国麻州波士顿都设有办公室 该公司最为人所熟知的产品是Java编程语言开发撰写时所用的集成开发环境 PhpStorm IntelliJ IDEA

随机推荐

  • frame 和iframe 的区别以及和frameset 的关系及应用

    1 frame不能脱离frameSet单独使用 iframe可以 2 frame不能放在body中 如下可以正常显示
  • C#让panel显示滚动条

    AutoScroll True AutoScrollMiniSize 450 450 设置逻辑区域尺寸 如果它大于控件尺寸就会出现滚动条
  • ffmpeg命令行示例

    在视频上覆盖一张照片 ffmpeg i video mkv i image png filter complex 0 v 1 v overlay out map out out mkv 生成5s的lavfi红色的视频 ffmpeg filt
  • mac brew安装 node 踩坑日记- n切换node不生效

    最近用了一个旧电脑开发 发现里面node管理混乱 有nvm n和homebrew 导致切换node 切换不了 开发也有莫名其妙的错误 所以我打算重新装一下node 使用n做为管理工具 1 删除nvm cd rm rf nvm 2 删除n s
  • 日语 五十音图快速记忆法

    平假名 清音 清音 段 段 段 段 段 行 a i u e o 行 ka ki ku ke ko 行 sa shi su se so 行 ta chi tsu te to 行 na ni nu ne no 行 ha hi fu he ho
  • 持久内存服务器大多数数据库管理系统,内存数据库VS传统数据库:如何在多个任务之间共享内存中的数据?...

    内存数据库 IMDB 将计算机数据存储在计算机的主存储器中 而不是磁盘驱动器中 以产生更快的响应时间 访问存储在内存中的数据可节省从磁盘查询数据所需的时间 依赖快速响应时间和实时数据管理的应用程序使用内存数据库 受益于内存数据库的行业包括电
  • PHY芯片的使用(三)在U-boot下网络PHY的移植

    1 概述 以太网 PHY 驱动移植 主要包括 Linux u boot 及设备树等三个方面标准框架下的移植 本文以裕太8511PHY为例展开说明 一般国产芯片厂商会提供在uboot linux下PHY的驱动 在uboot linux的PHY
  • 【MySQL入门指南】数据库基础DDL操作

    文章目录 MySQL库操作 一 SQL语句 二 创建数据库 1 语法 2 案例 3 极其不推荐的方式 三 查看数据库 1 语法 四 修改数据库 五 删除数据库 六 字符集与校验规则 1 是什么 2 相关指令 3 校验规则的影响 七 备份数据
  • 国外程序员推荐的好书

    1 代码大全 史蒂夫 迈克康奈尔 2 程序员修炼之道 3 计算机程序的构造和解释 4 C程序设计语言 5 算法导论 6 重构 改善既有代码的设计 7 设计模式 8 人月神话 9 计算机程序设计艺术 10 编译原理 龙书 11 深入浅出设计模
  • 使用GPU进行神经网络计算详解

    Pytorch学习笔记 六 使用GPU的简单LeNet网络模型中也提到了如何实现GPU上的运算 虽然不详细 但是也足够 总结 如果对于总结知识已经比较熟悉 那么下面的详解可以不用看 默认CPU进行计算 CPU上变量或模型不能与GPU上变量或
  • json转换javaBean属性值全null

    今天遇到了这么一个问题 解决办法分几步 所有转换javaBean的实体类实现序列化接口 将vo中不用于转换的属性剪掉 设置redis序列化方式为如下 Bean public RedisTemplate
  • JAVA多线程

    多线程 1 基本概念 1 1 程序 进程 线程 程序 完成一定功能的静态代码 对比火车站售票厅 进程 正在执行的静态代码 称为进程 对比北京西站售票 线程 为了并发执行一些异步任务 比对售票的中多个窗口 单核cpu和多核cpu java程启
  • 【机器学习】PCA、LDA、SVD

    线性变换 如果我们将向量 v 左乘矩阵 A 我们就会得到新的向量 b 也即可以表述说矩阵 A 对输入向量 v 执行了一次线性变换 且线性变换结果为 b 因此矩阵运算 Av b 就代表向量 v 通过一个变换 矩阵 A 得到向量 b 下面的实例
  • 智慧用电安全云监控系统

    近年来 我国电气火灾频发 2017年至2019年 我国共之间发生发展电气控制火灾31 1万起 占全国进行火灾总量及伤亡风险损失的30 以上 2019年全年共接报火灾23 3万起 电气火灾11 1万 占52 深圳市荣健市场 12 11 重大火
  • [项目管理-10]:软硬件项目管理 - 项目质量管理(质量)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 第10章 项目质量管理 10 1 基本概念 10 1 1 概述 10 1 2 项目的质量要求 10 1 3 项目质量的主要内容 10
  • ch1 密码学C/C++库介绍、C中大数的表示、接口语义

    Ch1 密码学C C 库介绍 话休絮烦 既然开了新坑 密码学C C 语言实现 就直接开始吧 这本书的作者是迈克尔 威尔森巴赫 Michael Welschenbach 是书籍的第二版 本书中描述的软件包名称为FLINT C 意思是 数论和密
  • JAVA直接量

    int a 2 char b f 类似以上的2 f 等为直接量 直接量可以是8种基本数据类型 也可以是null 但null只能复制给引用变量
  • 机器学习线性回归算法实验报告_机器学习——线性回归及kNN算法(作业)

    机器学习简介 人工智能AI 机器学习与深度学习 来自贪心学院课堂PPT 它们都是一种科学研究方法 宗旨即辅助人进行决策 减少人的不必要劳动时间 机器学习 训练模型 决策 判别 训练模型 前提选择已知的模型 如 LR kNN DT SVM M
  • 机器学习——交叉验证(留一法、自助法)

    文章目录 交叉验证的作用 留一法 自助法 交叉验证的作用 很多时候我们都在纠结 交叉验证法到底有啥用 我不用这个咋的 交叉验证是一种模型验证技术 可用于评估统计分析 模型 结果在其它独立数据集上的泛化能力 它主要用于预测 我们可以用它来评估
  • Scala入门到精通——第三节 Array、List

    本节主要内容 数组操作实战 列表List操作实战 数组操作实战 1 定长数组 定义一个长度为10的数值数组 scala gt val numberArray new Array Int 10 numberArray Array Int Ar