Scala详解(5)

Scala

集合

概述

  1. 集合本质上就是一个用于存储1个到多个数据的容器。在Scala中,集合可以分为三大类:Seq(序列),Set(集合)和Map(映射)。基于这三大类,衍生出来众多的子类

    1. 序列:元素有序可重复

    2. 集合:元素无序不可重复

    3. 映射:键值对结构数据

  2. 在Scala中,所有的集合都混入了Iterable特质,意味着所有的集合都可以被迭代遍历

  3. Scala中的集合分为可变集合(scala.collection.mutable)和不可变集合(scala.collection.immutable)

    1. 所谓的不可变集合,指的是集合被创建好之后,长度不可变,且其中的元素也不能改变。如果对不可变集合中的元素进行增删操作,那么不会改变原集合,而是会产生一个新的集合

    2. 所谓的可变集合,指的是集合创建好之后,依然可以对元素进行增删操作,并且不会产生新集合,而是修改原集合

数组

不可变数组(Array)
  1. 不可变数组定义好之后,长度不能发生变化,元素也不能增删;如果增删元素,那么会产生一个新的数组

  2. 定义方式

    package com.fesco.array
    ​
    object ArrayDemo {
    ​def main(args: Array[String]): Unit = {
    ​// 不可变数组定义方式
    ​// 方式一:val 数组名:Array[元素类型] = new Array[元素类型](数组长度)// 数组定义好之后,每一个位置都会有默认值val arr: Array[Int] = new Array[Int](5)arr(0) = 3// 将数组转化为字符串println(arr.mkString(","))
    ​// 方式二:// int[] arr = new int[]{3,4,1,4,5}val arr2: Array[Int] = Array(3, 1, 7, 8, 4)println(arr2.mkString(","))
    ​}
    ​
    }
  3. 应用一

    package com.fesco.array
    ​
    object ArrayDemo2 {
    ​def main(args: Array[String]): Unit = {
    ​// 不可变数组定义好之后长度不可变val arr = Array(2, 4, 8, 7, 1, 5, 6)
    ​// 应用一:修改数组中元素的值// 方式一:数组名(下标) = 数据arr(3) = 4// 方式二:提供了update方法来修改元素数据arr.update(2, 5)
    ​// 应用二:遍历数组// 方式一:转化为字符串val str = arr.mkString(", ")println(str)// 方式二:通过下标来遍历for (i <- 0 until arr.length) println(arr(i))// 方式三:增强for循环// 增强for循环本质上就是在对元素进行迭代遍历for (i <- arr) println(i)// 方式四:迭代遍历val it = arr.iteratorwhile (it.hasNext) println(it.next())// 方式五:foreach方法arr.foreach(x => println(x))// 顺次使用参数,并且参数只使用了一次arr.foreach(println(_))// println(3,5, (x, y) => x+ y)// println(3,5, _ + _ )// 函数体只有一句,并且使用了已经存在函数,且参数是一一对应,那么此时参数列表可以省略arr.foreach(println)
    ​
    ​}
    ​
    }
  4. 应用二

    package com.fesco.array
    ​
    object ArrayDemo3 {
    ​def main(args: Array[String]): Unit = {
    ​val arr = Array(2, 4, 8, 7, 1, 5, 6)
    ​// 应用三:数组扩容// Array类中提供了+:和:+的方式来对数组进行扩容,本质上都是产生一个新的数组// :+  在数组的末尾来新添元素,构成一个新的数组val r1 = arr :+ 3println(r1.mkString(", "))// +: 在数组的头部来新添元素,构成一个新的数组val r2 = arr.+:(3)println(r2.mkString(", "))val r3 = 3 +: arrprintln(r3.mkString(", "))val r4 = 4 +: arr :+ 3println(r4.mkString(", "))
    ​// 应用四:数组合并val nums1 = Array(1, 2, 3, 4, 5)val nums2 = Array(6, 7, 8, 9)// 方式一:通过++合并val v1 = nums1 ++ nums2println(v1.mkString(", "))// 方式二: ++: 或者 :++// ++:等价于++val v2 = nums1 ++: nums2println(v2.mkString(", "))val v3 = nums1 :++ nums2println(v3.mkString(", "))// 方式三:concat函数val v4 = nums1.concat(nums2)println(v4.mkString(", "))
    ​}
    ​
    }
  5. 应用三

    package com.fesco.array
    ​
    object ArrayDemo4 {
    ​def main(args: Array[String]): Unit = {
    ​// 应用五:创建连续范围的数组val r1 = Array.range(1, 5)println(r1.mkString(", "))val r2 = Array.range(0, 10, 2)println(r2.mkString(", "))
    ​// 应用六:用指定数据来填充数组// 创建数组,数组的所有元素默认为10// 第一个()表示数组长度// 第二个()表示填充的元素val v1 = Array.fill(5)(10)println(v1.mkString(", "))// 填充由100以内的随机数构成的长度为7的数组val v2 = Array.fill(7)((Math.random() * 100).toInt)println(v2.mkString(", "))// ({})可以选择省略()或者{}val v3 = Array.fill(7) {(Math.random() * 100).toInt}println(v3.mkString(", "))
    ​// 应用七:数组翻转val v4 = v3.reverseprintln(v4.mkString(", "))
    ​}
    ​
    }
  6. 练习:猴子报数。15只猴子围成一圈报数,报到数字7的猴子被淘汰,下一只猴子从1重新报数,最后剩余的是哪只猴子?

    package com.fesco.array
    ​
    object MonkeyExec {
    ​def main(args: Array[String]): Unit = {
    ​// 定义数组,表示15只猴子// 用true表示猴子的还活着,用false表示猴子被淘汰val monkeys = Array.fill(15)(true)// 定义变量来记录还剩余的猴子数量var n = 15// 定义变量来记录报数var i = 1// 定义变量来记录下标var index = 0// 只要剩余的猴子数量>1那么就需要继续报数while (n > 1) {// 先判断这只猴子是否存活if (monkeys(index)) {// 判断这只猴子是否会被淘汰if (i == 7) {// 这只猴子被淘汰monkeys(index) = false// 剩余猴子数量-1n -= 1// 下一只猴子重新报数i = 0}// 报数+1i += 1}// 下一只猴子准备index += 1if (index == monkeys.length) index = 0}println(monkeys.mkString(", "))}
    ​
    }
可变数组(ArrayBuffer)
  1. 可变数组,类似于Java中的ArrayList,长度可以发生变化,并且可以对数组中的元素来进行增删

  2. 定义格式

    package com.fesco.array
    ​
    import scala.collection.mutable.ArrayBuffer
    ​
    object ArrayBufferDemo {
    ​def main(args: Array[String]): Unit = {
    ​// 定义方式// 方式一:创建了可变数组,初始大小为0val r1 = new ArrayBuffer[Int]r1.+=(5)r1 += 3println(r1)// 方式二:创建可变数组,指定初始大小val r2 = new ArrayBuffer[Int](3)r2 += 4r2 += 2r2 += 5r2 += 7println(r2)// 方式三:创建可变数组,传入初始元素val r3 = ArrayBuffer[Int](2, 7, 8, 9, 1)println(r3)
    ​}
    ​
    }
  3. 基本操作

    package com.fesco.array
    ​
    import scala.collection.mutable.ArrayBuffer
    ​
    object ArrayBufferDemo2 {
    ​def main(args: Array[String]): Unit = {
    ​val arr = ArrayBuffer[Int](3, 4, 5, 6, 7)
    ​// 在末尾添加元素arr.+=(8)arr += 9arr.append(10)println(arr)// 在头部添加元素arr.prepend(2)println(arr)1 +=: arrprintln(arr)// 插入元素arr.insert(2, 11)println(arr)// 修改元素arr(0) = 0println(arr)arr.update(1, 3)println(arr)// 删除指定下标上的元素arr.remove(0)println(arr)// 删除元素3// 删除指定的元素(第一次出现)arr -= 3println(arr)// 遍历arr.foreach(println)
    ​}
    ​
    }
转换
package com.fesco.array
​
import scala.collection.mutable.ArrayBuffer
​
object ArrayTransformDemo {
​def main(args: Array[String]): Unit = {
​// 可变数组 -> 不可变数组val arrBuffer = ArrayBuffer[Int](2, 3, 4, 5)val arr = arrBuffer.toArrayprintln(arr)
​// 不可变数组 -> 可变数组val array = Array[Int](1, 2, 3, 4, 5)val buffer = array.toBufferprintln(buffer)
​}
​
}
多维数组
  1. 定义格式

    package com.fesco.array
    ​
    object DimensionDemo {
    ​def main(args: Array[String]): Unit = {
    ​// 定义格式
    ​// 方式一:// 定义二维数组r1,包含了3个一维数组,每一个一维数组的大小是不确定的val r1: Array[Array[Int]] = new Array[Array[Int]](3)r1(0) = new Array[Int](5)r1(1) = Array[Int](1, 2, 3, 4)
    ​// 方式二:// 定义二维数组r2包含了2个一维数组val r2 = Array(Array(1, 2, 3), Array(1, 3, 4, 6))println(r2(0)(1))
    ​// 方式三:// 通过ofDim函数来构建二维数组// 定义二维数组r3,包含了3个一维数组,每一个一维数组包含了5个元素val r3 = Array.ofDim[Int](3, 5)r3(0)(0) = 3println(r3(0)(0))
    ​// 一维数组,可以包含4个整数val r4 = Array.ofDim[Int](4)// 三维数组,包含了4个二维数组,每一个二维数组中包含了3个一维数组,每一个一维数组可以包含5个整数var r5 = Array.ofDim[Int](4, 3, 5)// 四维数组,包含了3个三维数组,每一个三维数组中包含了4个二维数组,每一个二维数组中包含了5个一维数组,每一个一维数组可以有2个整数var r5 = Array.ofDim[Int](3, 4, 5, 2)
    ​}
    ​
    }
  2. 如果每一个一维数组等大,那么推荐使用第三种方式;如果包含的一维数组不等大,使用方式一;如果已知元素,那么使用方式二

  3. ofDim支持多维数组:一维~五维数组。Scala中不推荐超过5维的数组

  4. 练习:输入一个数字n表示行数,输出杨辉三角的前n行

    package com.fesco.array
    ​
    import scala.io.StdIn
    ​
    object DimensionExec {
    ​def main(args: Array[String]): Unit = {
    ​/*11 11 2 11 3 3 11 4 6 4 1...*/// 获取整数nval n = StdIn.readInt()// 定义二维数组val arr = new Array[Array[Int]](n)// 遍历数组for (i <- 0 until n) {// 初始化第i行一维数组arr(i) = new Array[Int](i + 1)// 填充元素for (j <- 0 to i) {// 每一行第一个或者最后一个元素是1if (j == 0 || j == i) arr(i)(j) = 1else arr(i)(j) = arr(i - 1)(j) + arr(i - 1)(j - 1)}println(arr(i).mkString("\t"))}
    ​}
    ​
    }

列表

不可变列表(List)
  1. 在Scala中,通过List来定义不可变列表,需要注意的是,List本身是一个抽象类,所以并不能直接使用List来构建对象,需要使用它的伴生对象来构建

    package com.fesco.list
    ​
    import scala.::
    ​
    object ListDemo {
    ​def main(args: Array[String]): Unit = {
    ​// 方式一val list = List[Int](2, 3, 4, 5, 6)println(list)val list2 = List.apply(2, 3, 4, 5, 6)println(list2)
    ​// 方式二:// :: 在list之前来追加数据val list3 = 1 :: listprintln(list3)
    ​// 方式三:// Nil是List的子类,表示一个空列表val list4 = Nilprintln(list4)
    ​// 方式四:val list5 = 1 :: 2 :: 3 :: 4 :: Nilprintln(list5)}
    ​
    }
  2. List被sealed修饰,说明List是一个密封类,那么就意味着List的子类必须和List处在同一个scala文件中,即List无法直接扩展

  3. 基本操作

    package com.fesco.list
    ​
    object ListDemo2 {
    ​def main(args: Array[String]): Unit = {
    ​val list = List[Int](3, 4, 8, 1, 5, 9, 7)
    ​// 获取指定下标位置上的元素// 底层实际上是调用了父特质LinearSeq中的apply函数println(list(2))// 等价于println(list.apply(2))// 获取第一个元素// println(list(0))// 等价于println(list.head)// 获取最后一个元素println(list.last)// 追加一个元素 - 产生一个新的列表// val r1 = list :+ 6val r1 = list.:+(6)println(r1)// 在头部追加元素// 从右向左计算val r2 = 1 +: list// val r2 = list.+:(1)// 当出现:的时候,:对着谁就从谁开始计算// 如果两边都有:,那么从右向左计算// 错误的写法:list +: 1println(r2)// 或者// val r3 = list.::(1)val r3 = 1 :: list// list :: 1println(r3)// 构建了列表// 从右到左:先构建空列表List(),然后头部拆入5,在插入4val r4 = 1 :: 2 :: 3 :: 4 :: 5 :: List()// 等价于val r5 = 1 :: 2 :: 3 :: 4 :: 5 :: Nilprintln(r4)println(r5)
    ​}
    ​
    }
  4. 列表的合并

    package com.fesco.list
    ​
    object ListDemo3 {
    ​def main(args: Array[String]): Unit = {
    ​val list1 = List[Int](1, 2, 3, 4)val list2 = List[Int](5, 6, 7, 8)
    ​// 合并列表val r1 = list1 ++ list2println(r1)val r2 = list1 ++: list2println(r2)val r3 = list1 :++ list2println(r3)val r4 = list1.concat(list2)println(r4)val r5 = list1 ::: list2println(r5)
    ​}
    ​
    }
可变列表(ListBuffer)
  1. Scala中,通过ListBuffer来定义可变列表

    package com.fesco.list
    ​
    import scala.collection.mutable.ListBuffer
    ​
    object ListBufferDemo {
    ​def main(args: Array[String]): Unit = {
    ​// 方式一// 调用ListBuffer类的主构造器val buffer1 = new ListBuffer[Int]()buffer1 += 4println(buffer1)// 方式二// 调用了ListBuffer伴生对象中的apply函数val buffer2 = ListBuffer[Int](1, 2, 3, 4, 5)println(buffer2)
    ​}
    ​
    }
  2. 基本操作

    package com.fesco.list
    ​
    import scala.collection.mutable.ListBuffer
    ​
    object ListBufferDemo2 {
    ​def main(args: Array[String]): Unit = {
    ​val list = ListBuffer[Int](1, 2, 3, 4, 5)
    ​// 在尾部追加元素list += 4list append 7println(list)// 在头部插入元素list prepend 0// list.+=:(2)2 +=: listprintln(list)// 在指定下标位置上插入元素list.insert(3, 6)println(list)// 修改指定位置上的元素list(2) = 10list.update(3, 12)println(list)// 删除指定下标位置上的元素list.remove(0)println(list)// 删除指定的元素(第一个)list -= 3println(list)
    ​}
    ​
    }
  3. 合并列表

    package com.fesco.list
    ​
    import scala.collection.mutable.ListBuffer
    ​
    object ListBufferDemo3 {
    ​def main(args: Array[String]): Unit = {
    ​val list1 = ListBuffer[Int](1, 2, 3)val list2 = ListBuffer[Int](4, 5, 6)
    ​// 将list1和list2合并// ++合并之后产生一个新的列表,而不是修改原列表val r1 = list1 ++ list2println(r1)// 要求:将list2中的数据合并到list1中list1 ++= list2println(list1)// 获取list1中有而list3中没有的数据 - 差集val list3 = ListBuffer[Int](1, 3, 5, 7)list1 --= list3println(list1)
    ​}
    ​
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/823151.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过控制台获取iptv直播地址

控制台代码1: // 获取所有包含频道名称和URL的<div>和<td>元素 const divElements = document.querySelectorAll(div[style="float: left;"]); const tdElements = document.querySelectorAll(td[style="padding-left: 6px;"]);// 创建空数组…

2011年认证杯SPSSPRO杯数学建模C题(第二阶段)你的爱车入保险了吗全过程文档及程序

2011年认证杯SPSSPRO杯数学建模 C题 你的爱车入保险了吗 原题再现&#xff1a; 近几年&#xff0c;国内汽车销售市场异常火爆&#xff0c;销售量屡创新高。车轮上的世界&#xff0c;保险已经与我们如影随形。汽车保险&#xff0c;简称车险&#xff0c;是指对机动车辆由于自然…

计算机考研都将采用408!?

这个根本不可能&#xff0c;高考还没做到全国统一考试呢 每个学校对于计算机招生的需求是不一样的&#xff0c;比如清华大学&#xff0c;专业课912&#xff0c;算的上是最难的计算机专业课了&#xff0c;那他为什么搞这么难啊&#xff0c;还不是因为那群敢考清华的卷王们太变态…

Python数据结构【二】查找

前言 可私聊进一千多人Python全栈交流群&#xff08;手把手教学&#xff0c;问题解答&#xff09; 进群可领取Python全栈教程视频 多得数不过来的计算机书籍&#xff1a;基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。 &#x1f680;&a…

C++奇迹之旅:构造函数

文章目录 &#x1f4dd;类的6个默认成员函数&#x1f320; 构造函数&#x1f309; 概念&#x1f309;特性&#x1f309;三种默认构造函数 &#x1f6a9;总结 &#x1f4dd;类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&am…

【重磅开源】一款可以生成SpringBoot+Vue代码的轻量级项目

基于SpringBootVue3开发的轻量级快速开发脚手架 &#x1f341;项目简介 一款通用的前、后端项目模板 一款快速开发管理系统的项目 一款可以生成SpringBootVue代码的项目 一款持续迭代的开源项目 一个程序员的心血合集 度过严寒&#xff0c;终有春日&#xff…

FastJson转化时BigDecimal与Double问题

一、场景 在使用FastJson将json字符串转化为jsonObject时&#xff0c;FastJson默认会将小数转为BigDecimal类型&#xff0c;但有时候我们想要的是double类型。 二、解决方案 int disableDecimal JSON.DEFAULT_PARSER_FEATURE & ~Feature.UseBigDecimal.getMask(); Stri…

Nginx内存池相关源码剖析(一)总览

剖析nginx的内存池源码&#xff0c;讲解原理实现以及该内存池设计的应用场景 介绍 Nginx内存池是Nginx为了优化内存管理而引入的一种机制。在Nginx中&#xff0c;每个层级&#xff08;如模板、TCP连接、HTTP请求等&#xff09;都会创建一个内存池进行内存管理。当这些层级的…

Linux下redis的安装过程与配置详细教程【5.0.5为例子】

Linux下redis的安装过程与配置方法【5.0.5为例子】 下载redis redis下载地址 https://download.redis.io/releases/ 也可以自行去官网下载 提示&#xff1a;此处安装的为redis-5.05的版本 上传redis安装包(我的安装目录为/data/tool/redis-5.0.5) 创建目录/data/local/tool并…

Day20-【Java SE高级】单元测试 反射 注解 动态代理

一、单元测试 就是针对最小的功能单元(方法)&#xff0c;编写测试代码对其进行正确性测试。 1. 咱们之前是如何进行单元测试的?有啥问题? 只能在main方法编写测试代码&#xff0c;去调用其他方法进行测试。无法实现自动化测试&#xff0c;一个方法测试失败&#xff0c;可能…

Day 23 669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树 总结篇

修剪二叉搜索树 给定一个二叉搜索树&#xff0c;同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[L, R]中 (R>L) 。你可能需要改变树的根节点&#xff0c;所以结果应当返回修剪好的二叉搜索树的新的根节点。 ​ 最直接的想法&#xff0…

最强解释!Python 包的依赖管理,有解了!

之前一直比较抵触用 Python &#xff0c;很大一部分原因是觉得 Python 项目的环境管理比较混乱。Node.js 有 Npm 包管理工具&#xff0c;通过 package.json 配置项目依赖&#xff0c;最多再通过 nvm 来进行环境切换&#xff1b;Java 有 Maven Gradle 来进行包管理和项目依赖配置…

python操作Excel文件

python操作Excel小记 不重要 不重要 不重要 不重要 不重要 不重要 def saveData(all_data:list,hotelName:str,hotelIndex:int) -> None:if not os.path.exists(r.\data\酒店数据.xlsx):# Excel文件不存在,则创建Excel文件wb = Workbook()# 创建页表ws = wb.create_sheet(…

今天刷两题(day2)

题目一&#xff1a;最长公共前缀 题目描述&#xff1a; 给你一个大小为 n的字符串数组 strs &#xff0c;其中包含n个字符串 , 编写一个函数来查找字符串数组中的最长公共前缀&#xff0c;返回这个公共前缀。输入输出描述&#xff1a; 输入&#xff1a;"abca","…

MyBatis 源码分析 - SQL 的执行过程

MyBatis 源码分析 - SQL 的执行过程 * 本文速览 本篇文章较为详细的介绍了 MyBatis 执行 SQL 的过程。该过程本身比较复杂&#xff0c;牵涉到的技术点比较多。包括但不限于 Mapper 接口代理类的生成、接口方法的解析、SQL 语句的解析、运行时参数的绑定、查询结果自动映射、延…

C++ 秋招必知必会(数据结构与算法:下)

20. 二叉树的定义与操作 二叉树&#xff08;binary tree&#xff09;是一种非线性数据结构&#xff0c;代表着祖先与后代之间的派生关系&#xff0c;体现着“一分为二”的分治逻辑 与链表类似&#xff0c;二叉树的基本单元是节点&#xff0c;每个节点包含&#xff1a;值、左子…

Vue3---基础6(标签的ref属性)

标签的 ref 属性 作用&#xff1a;用于注册模版引用 用在普通DOM标签上&#xff0c;获取的是DOM节点 用在组件标签上&#xff0c;获取的是组件实例对象 普通DOM标签 <template><div class"person"><h1>中国</h1><h2 ref"2">…

MYSQL5.7详细安装步骤

MYSQL5.7详细安装步骤&#xff1a; 0、更换yum源 1、打开 mirrors.aliyun.com&#xff0c;选择centos的系统&#xff0c;点击帮助 2、执行命令&#xff1a;yum install wget -y 3、改变某些文件的名称 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base…

储能的全生命周期成本即平准化度电成本的计算方法及python实践

1. 平准化度电成本&#xff08;LCOE&#xff09;是一种衡量电力项目经济性的指标 LCOE&#xff08;Levelized Cost of Energy,&#xff09;的概念最早由美国国家可再生能源实验室&#xff08;NREL&#xff09;在1995年提出&#xff0c;它是通过将一个项目生命周期内的所有成本…

绩效考核:关键绩效指标(KPI)

绩效管理是企业人力资源管理的核心内容之一&#xff0c;而绩效考核又是绩效管理的关键环节。在绩效考核中&#xff0c;关键绩效指标&#xff08;KPI&#xff09;的应用越来越广泛。本文将介绍关键绩效指标&#xff08;KPI&#xff09;的概念、意义、制定方法以及应用实例&#…