Scala学习笔记13: 集合

目录

    • 第十三章 集合
      • 1- 列表 (List)
      • 2- 集 (Set)
      • 3- 映射 (Map)
      • 4- 数组 (Array)
      • 5- 元组 (Tuple)
      • 6- 可变和不可变集合
      • 7- 添加或者去除元素
      • 8- 化简、折叠和扫描
      • 9- 拉链操作
      • 10- 迭代器
      • end

第十三章 集合

在Scala中, 集合 (Collections) 是一种重要的数据结构, 用于存储和操作一组元素 ;

Scala提供了丰富的集合类库, 包括可变和不可变的集合类型, 以及各种高阶函数和操作符, 方便对集合进行操作和转换 ;

常见的Scala集合类型包括:

  1. 列表 (List) : 有序集合, 元素可重复, 使用 List 关键字定义 ;
  2. 集 (Set) : 无须集合, 元素不重复, 使用 Set 关键字定义 ;
  3. 映射 (Map) : 键值对集合, 键不重复, 值可重复, 使用 Map 关键字定义 ;
  4. 数组 (Array) : 定长可变集合, 使用 Array 关键字定义 ;
  5. 元组 (Tuple) : 不同类型元素的有序集合, 使用 (value1, value2, …) 定义 ;

1- 列表 (List)

在Scala中, 列表 (List) 是一种不可变的有序集合, 允许元素重复 ;

列表是基于链表结构实现的, 每个列表都由一个头部元素和一个指向剩余元素列表的尾部组成 ;

Scala的列表提供了丰富的操作方法, 如 mapfilterfoldLeft 等, 用于对列表进行转换和操作 ;

示例:

    // 1. 创建列表: 可以使用List关键字创建列表val numbers = List(1, 2, 3, 4, 5)// 2. 访问元素: 可以使用索引访问列表中的元素, 索引从0开始val firstElement = numbers(0)println(firstElement) // 输出: 1// 3. 操作列表: 可以使用map, filter, reduce等方法对列表进行操作val doubledNumbers = numbers.map(_ * 2)println(doubledNumbers) // 输出: List(2, 4, 6, 8, 10)val evenNumbers = numbers.filter(_ % 2 == 0)println(evenNumbers) // 输出: List(2, 4)val sum = numbers.reduce(_ + _)println(sum) // 输出: 15// 4. 连接列表: 可以使用 `::` 操作符将元素添加到列表的开头val newNumbers = 0 :: numbersprintln(newNumbers) // 输出: List(0, 1, 2, 3, 4, 5)// 5. 列表模式匹配: 可以使用模式匹配来处理列表中的元素val (head, tail) = numbers match {case h :: t => (h, t)case _ => (0, Nil)}println(head) // 输出: 1println(tail) // 输出: List(2, 3, 4, 5)

Scala的列表是不可变的, 这意味着列表的内容在创建后不可更改 ;

如果需要可变列表, 可以使用 scala.collection.mutable.ListBuffer .

2- 集 (Set)

在Scala中, 集合 (Set) 是一种不可变的元素集合, 其中元素不重复 ;

Scala的集合库提供了 Set 特质以及不可变和可变的具体实现, 用于存储一组唯一的元素 ;

集合在Scala中通常用于快速查找和去重操作 ;

示例:

    // 1. 创建集合: 可以使用 `Set` 关键字创建集合val numberSet = Set(1, 2, 3, 4, 5)// 2. 添加元素: 集合是不可变的, 无法直接添加元素, 但可以通过创建新的集合来添加元素val newNumberSet = numberSet + 6// 3. 操作集合: 可以使用集合的 `map` 方法来对集合中的每个元素进行操作, `insersect` 方法来求交集, `union` 方法来求并集val otherSet = Set(3, 4, 5, 6, 7)val intersectSet = numberSet.intersect(otherSet)val unionSet = numberSet.union(otherSet)println(intersectSet) // 输出: Set(5, 3, 4)println(unionSet) // 输出: Set(5, 1, 6, 2, 7, 3, 4)// 4. 检查元素: 可以使用 `contains` 方法来检查集合中是否包含某个元素val containsFive = numberSet.contains(5)println(containsFive) // 输出: true// 5. 遍历集合: 可以使用 `foreach` 方法来遍历集合中的每个元素numberSet.foreach(println)// 输出:// 5// 1// 2// 3// 4

Scala的集合库还提供了丰富的方法和操作符, 用于对集合进行操作和转换 ;

集合在Scala中是非常常用且强大的数据结构, 适应于各种场景 .

3- 映射 (Map)

在Scala中, 映射 (Map) 是一种键值对的集合, 用于存储一组唯一的键和对应的值 ;

Scala的映射是基于哈希表实现的, 可以快速查找和访问键值对 ;

映射在Scala中非常常用, 用于表示各种数据关系和映射关系 ;

示例:

    // 1. 创建映射: 可以使用 `Map` 关键字创建映射val personInfo = Map("name" -> "Jim", "age" -> 18)// 2. 访问值: 可以通过键访问映射中的值val name = personInfo("name")val age = personInfo.getOrElse("age", 0)println(s"name: $name, age: $age") // name: Jim, age: 18// 3. 添加值: 映射不可变, 无法直接添加键值对, 可以通过创建新的映射来添加键值对, 可以使用 `+` 运算符添加键值对val newPersonInfo = personInfo + ("gender" -> "male")println(newPersonInfo) // Map(name -> Jim, age -> 18, gender -> male)// 4. 操作映射: 可以使用各种方法对映射进行操作, 例如: `keys` 获取所有键, `values` 获取所有值, `contains` 判断是否存在键val keys = personInfo.keysval values = personInfo.valuesprintln(keys) // Set(name, age)println(values) // MapLike(Jim, 18)println(personInfo.contains("name")) // trueprintln(personInfo.contains("gender")) // false// 5. 遍历映射: 可以使用 `foreach` 方法遍历映射, 并执行指定的操作personInfo.foreach {case (key, value) => println(s"$key: $value")}/* 输出结果:name: Jimage: 18*/

Scala的映射提供了丰富的方法和操作符, 用于对键值对进行操作和转换 ;

映射是一种非常有用的数据结构, 适应于各种场景, 如配置信息, 数据索引等 .

4- 数组 (Array)

在Scala中, 数组 (Array) 是一种可变的有序集合, 用于存储固定大小的元素 ;

Scala的数组与Java的数组类似, 但Scala的数组可以是泛型的, 运行存储不同类型的元素 ;

数组在Scala中是一种基本的数据结构, 常用于需要高性能和可变性的场景 ;

示例:

    // 1. 创建数组: 可以使用 `Array` 关键字创建数组val numbers = Array(1, 2, 3, 4, 5)// 2. 访问元素: 可以使用索引访问数组中的元素, 索引从0开始val firstNumber = numbers(0)println(firstNumber) // 输出: 1// 3. 更新元素: 由于数组是可变的, 可以使用索引更新数组中的元素numbers(0) = 10println(numbers(0)) // 输出: 10// 4. 操作数组: 可以使用 `map` 方法对数组进行操作, 例如将数组中的每个元素乘以2; `filter` 方法对数组进行过滤, 例如只保留偶数;val doubledNumbers = numbers.map(_ * 2)println(doubledNumbers.mkString(", ")) // 输出: 20, 4, 6, 8, 10val evenNumbers = numbers.filter(_ % 2 == 0)println(evenNumbers.mkString(", ")) // 输出: 2, 4// 5. 遍历数组: 可以使用 `foreach` 方法遍历数组numbers.foreach(println) // 输出: 10 2 3 4 5// 6. 转换为列表: 可以使用 `toList` 方法将数组转换为列表val numbersList = numbers.toListprintln(numbersList) // 输出: List(10, 2, 3, 4, 5)

Scala的数组提供了高性能和可变性, 适应于需要频繁修改元素的场景 ;

但需要注意的是, 数组是可变的数据结构, 可能引入一些副作用, 因此在函数式编程中建议尽量使用不可变的集合 .

5- 元组 (Tuple)

在Scala中, 元组 (Tuple) 是一种不可变的有序集合, 用于存储固定数量的元素 ;

元组可以包含不同类型的元素, 并且元组的长度是固定的 ;

Scala的元组提供了一种方便的方式来组合和传递多个值, 而不需要创建新的类或结构 ;

示例:

    // 1. 创建元组: 可以使用小括号和逗号创建元组val person = ("Tom", 18, "London")// 2. 访问元组: 可以使用 `.` 和索引访问元组中的元素, 索引从1开始val name = person._1val age = person._2val city = person._3println(name) // 输出: Tomprintln(age) // 输出: 18println(city) // 输出: London// 3.元组模式匹配: 可以使用模式匹配来解构元组person match {case (name, age, city) => println(s"$name is $age years old, and lives in $city.")}// 输出: Tom is 18 years old, and lives in London.// 4. 元组转换为列表: 可以使用 `.toList` 方法将元组转换为列表val personList = person.productIterator.toListprintln(personList) // 输出: List(Tom, 18, London)// 5. 遍历元组: 可以使用 `.foreach` 方法遍历元组中的每个元素person.productIterator.foreach(println)/* 输出:Tom18London*/

元组的特性: 元组子啊Scala中常用于返回多个值的函数 、临时组合数据等场景 , 具有简洁和灵活的特性 ;

Scala的元组是一种轻量级的数据结构, 适用于需要临时组合多个值的情况 ;

元组的不可变性和固定长度使其在某些场景下非常有用 .

6- 可变和不可变集合

在Scala中, 集合可以分为可变 (mutable) 和不可变 (immutable) 两种类型 ;

不可变集合是指一旦创建就无法更改的集合, 任何修改操作都会返回一个新的集合, 原集合保持不变 ;

相反, 可变集合允许在原地修改其内容, 即可以直接修改集合而不需要创建新的集合 .

不可变集合在Scala中是更常用的选择, 因为他们具有线程安全性和函数式编程的优点 ;

不可变集合的操作不会改变原始集合, 而返回一个新的不可变集合, 这有助于避免副作用和提高代码的可维护性 .

可变集合则适用于需要频繁修改数据的场景, 因为他们允许直接在原地修改集合内容, 而不是创建新的集合 ;

可变集合在某些情况下可以提供更高的性能, 但也需要更多的注意力来管理状态变化 ;

在Scala中, 不可变集合通常位于 scala.collection.immutable 包中, 而可变集合位于 scala.collection.mutable 包中 ;

开发者可以根据具体需求和场景选择合适的集合类型, 以实现更安全、高效的编程 .

7- 添加或者去除元素

在Scala中, 集合中常用的方法用于添加或去除元素包括 ++::+ ;

  1. + : 对于不可变无顺序的集合, + 方法用于向集合中添加元素并返回一个新的集合, 原集合保持不变 ; 例如: 对于Set集合:

        val set = Set(1, 2, 3, 4, 5)val newSet = set + 6println(newSet) // Set(5, 1, 6, 2, 3, 4)
    
  2. +: : 对于List集合, +: 方法用于在列表的头部添加元素并返回一个新的列表, 原列表保持不变 ; 例如:

        val list = List(3,4,5)val newList = 1 +: listprintln(newList) // List(1, 3, 4, 5)
    
  3. :+ : 对于List集合, :+ 方法用于在列表的尾部添加元素并返回一个新的列表, 原列表保持不变 ; 例如:

        val list = List(3,4,5)val newList = list :+ 6println(newList) // List(3, 4, 5, 6)
    

    这些操作符都会返回新的集合, 不会修改原有的集合 .

8- 化简、折叠和扫描

在Scala中, 集合的化简 (reduce) 、折叠(fold) 和扫描(scan) 是常用的函数式编程操作, 用于对集合中的元素进行聚合计算 ;

  1. 化简 (reduce) :

    • reduce 函数将集合中的元素两两结合, 递归地将结果与下一个元素结合, 最终返回一个值 ;

    • 示例: 对列表中的元素求和

    •     val list = List(1, 2, 3, 4, 5)val sum = list.reduce(_ + _)println(sum) // 15
      
  2. 折叠 (fold) :

    • fold 函数接受一个初始值和一个二元操作函数, 从初始值开始, 将集合中的元素依次应用于操作函数, 返回最终结果 ;

    • 示例: 对列表中的元素求和, 初始值为 1000

    •     val list = List(1, 2, 3, 4, 5)val sum = list.fold(100)((x, y) => x + y) // list.fold(100)(_ + _)println(sum) // 115
      
  3. 扫描 (scan) :

    • scan 函数类似于 fold , 但会返回每一步的中间结果组成的集合 ;

    • 示例: 对列表中的元素进行累加扫描

    •     val list = List(1, 2, 3, 4, 5)val scanResult = list.scan(-3)(_ + _)println(scanResult) // List(-3, -2, 0, 3, 7, 12)val scanLeftResult = list.scanLeft(-3)(_ + _) // 从左到右println(scanLeftResult) // List(-3, -2, 0, 3, 7, 12)val scanRightResult = list.scanRight(-3)(_ + _) // 从右到左println(scanRightResult) // List(12, 11, 9, 6, 2, -3)
      

9- 拉链操作

在Scala中, 拉链操作 (zip) 是一种常见的集合操作, 用于将两个集合的对应元素进行配对 ;

具体来说, 拉链操作会将两个集合中相同位置的元素组成一个元组, 生成一个新的集合 ;

示例:

    val list1 = List(1, 2, 3, 4, 5)val list2 = List("A", "B", "C", "D", "E")val list3 = list1 zip list2println(list3) // List((1,A), (2,B), (3,C), (4,D), (5,E))// 如果两个列表元素个数不同, 以最少的进行匹配val list1 = List(1, 2, 3, 4)val list2 = List("A", "B", "C", "D", "E")val list3 = list1 zip list2println(list3) // List((1,A), (2,B), (3,C), (4,D)

在上面的示例中, list1list2 分别是两个不同类型的集合, 通过 zip 方法进行拉链操作后, 生成了一个包含元组的新集合 list3 , 其中每个元组包含了两个集合对应位置的元素 ;

拉链操作在处理需要将两个集合的元素一一对应的情况下非常有用, 可以方便地将两个集合进行配对操作 .

10- 迭代器

在Scala中, 可以使用迭代器 (Iterator) 来遍历集合 ;

迭代器提供了一种逐个访问集合元素的方式, 适用于需要逐个处理集合元素的场景 ;

示例: 使用迭代器遍历集合的基本方法

    val list = List(1, 2, 3, 4, 5)val it = list.iteratorwhile (it.hasNext) {println(it.next())}/* 输出: 12345*/
  • 在上面的示例中, 首先创建了一个整数列表 list , 然后通过 iterator 方法获取了该列表的迭代器 it ;
  • 接着使用 while 循环和 hasNext 方法判断是否还有下一个元素, 然后使用 next 方法逐个访问并处理元素 .

除了使用 while 循环外, 还可以使用 foreach 方法来简化迭代器的遍历:

    val list = List(1, 2, 3, 4, 5)val it = list.iteratorit.foreach(println) /*12345*/

通过以上方法, 您可以方便地使用迭代器遍历Scala集合中的元素 .

end

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

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

相关文章

PostgreSQL源码分析——psql

psql是一个PostgreSQL数据库自带的客户端工具,用来与数据库进行交互,当然,你也可以用其他工具。这里,我们简单分析一下psql工具的实现。 主流程如下 psql的核心功能,连接数据库,执行用户的命令&#xff0…

定制汽车霍尔传感器

磁电效应霍尔传感器、饱和霍尔传感器、非线性霍尔传感器 霍尔传感器原理 霍尔传感器的工作原理基于霍尔效应,即当一块通有电流的金属或半导体薄片垂直地放在磁场中时,薄片的两端会产生电位差。这种现象称为霍尔效应,两端具有的电位差值称为…

嵌入式实验---实验二 中断功能实验

一、实验目的 1、掌握STM32F103中断程序设计流程; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、在上一章的实验基础上,添加一个按键和一个LED; 2、使用中断的方式实现以下两个功能: (1)KEY1按键…

【git】gitee仓库本地克隆失败可能的一种解决办法

出错点: 在 gitee 克隆远程仓库到 本地时,可能会出现以下报错情况,无法成功克隆 正常流程:(熟悉正常克隆流程的可以直接跳到下面的【解决办法】) 我们一般复制仓库地址是在下面红线框框的位置&#xff0c…

华为云与AWS负载均衡服务深度对比:性能、成本与可用性

随着云计算的迅速发展,企业对于云服务提供商的选择变得越来越关键。在选择云服务提供商时,负载均衡服务是企业关注的重点之一。我们九河云将深入比较两大知名云服务提供商华为云和AWS的负载均衡服务,从性能、成本和可用性等方面进行对比。 AW…

知识库的创建(4) - KBServiceFactory:获取不同类型知识库服务的工厂类

文章目录 前言一、 方法详解1. get_service2. get_service_by_name3. get_default 二、 代码注释总结 前言 上一篇我们在update_docs里看到了 KBServiceFactory.get_service_by_name(knowledge_base_name),这一篇我们一起来看看KBServiceFactory类 KBServiceFactor…

数据赋能(124)——体系:数据格式化——影响因素、直接作用、主要特征

影响因素 数据格式化过程中需要考虑的一些影响因素: 数据质量和准确性: 数据清洗:在格式化之前,应确保数据的质量和准确性。这包括去除重复数据、处理缺失值、纠正错误数据等。数据验证:在格式化过程中,应…

P1656 炸铁路

题目描述 A 国派出将军 uim,对 B 国进行战略性措施,以解救涂炭的生灵。 B 国有 n 个城市,这些城市以铁路相连。任意两个城市都可以通过铁路直接或者间接到达。 uim 发现有些铁路被毁坏之后,某两个城市无法互相通过铁路到达。这…

Vue--》从零开始打造交互体验一流的电商平台(三)

今天开始使用 vue3 + ts 搭建一个电商项目平台,因为文章会将项目的每处代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的github上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关注本专栏,学习更多…

leetcode刷题(46-50)

算法是码农的基本功,也是各个大厂必考察的重点,让我们一起坚持写题吧。 遇事不决,可问春风,春风不语,即是本心。 我们在我们能力范围内,做好我们该做的事,然后相信一切都事最好的安排就可以啦…

【机器学习】 第1章 概述

一、概念 1.机器学习是一种通过先验信息来提升模型能力的方式。 即从数据中产生“模型”( model )的算法,然后对新的数据集进行预测。 2.数据集(Dataset):所有数据的集合称为数据集。 训练集:用来训练出一个适合模…

TCP/UDP协议传输

TCP 客户端 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h>//宏定义错误输出格式>>>>类比封装函数#…

什么是无限铸币攻击?它是如何运作的?

一、无限铸币攻击解释 无限铸币攻击是指攻击者操纵合约代码不断铸造超出授权供应限制的新代币。 这种黑客行为在去中心化金融 (DeFi) 协议中最为常见。这种攻击通过创建无限数量的代币来损害加密货币或代币的完整性和价值。 例如&#xff0c;一名黑客利用了 Paid 网络的智能…

ansible 模块进阶及变量

yum 模块进阶 - name: install pkgs hosts: webservers tasks: - name: install web pkgs # 此任务通过yum安装三个包 yum: name: httpd,php,php-mysqlnd state: present # 根据功能等&#xff0c;可以将一系列软件放到一个组中&#xff0c;安装软件包组&#xff0c;将会把很…

shell脚本之数组及冒泡排序

1.数组定义&#xff1a;在集合当中指定多个元素&#xff0c;元素的类型可以是整数、字符串及浮点。 2.数组作用&#xff1a;一次性的定义多个元素&#xff0c;可以为变量赋值提供便利。 3.数组的定义方法&#xff1a; 数组名&#xff08;a b c d&#xff09; 数组名不能重复…

IPV6配置二

IV6 的单播路由协议-----在使用路由协议前一定需要开启 IPV6的单播路由功能&#xff0c;否则不转发IPV6的流量 【1】IPV6 静态路由协议&#xff1a; (1)普通静态路由 rl(config)#ipv6 route 2::/64 serial 1/1 rl(config)#ipv6 route 2::/64 12:2 &#xff1f; …

【速过】2024年9月三级数据库技术题库+知识点总结

24年3月已经考了一次数据库&#xff0c;实话&#xff0c;三级比二级简单一些&#xff0c;知识点都比较集中&#xff0c;50%-60%是题库里面的原题&#xff0c;考前只要好好的过一遍题库考到80以上完全没有问题&#xff0c;你实在不会答案背下来也是可以的&#xff0c;不过更多的…

kotlin函数

1、函数定义 // 下边定义了main函数 fun main() {} 2、函数的类型 // foo函数定义 fun foo () {} // 对应无参类型 () -> Unit fun foo (a: Int):String {} // 对应有参类型 (Int) -> String 3、函数的引用 函数的引用类似C语言中的函数指针&#xff0c;可用于函数传…

外包干了2年,彻底废了...

先说一下自己的情况。大专生&#xff0c;17年通过校招进入湖南某软件公司&#xff0c;干了接近2年的点点点&#xff0c;今年年上旬&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了五年的功能测试…

选择江苏显卡服务器租用的优势有哪些?

显卡服务器有着强大的计算功能&#xff0c;可以使用图形处理器进行计算与运算&#xff0c;十分适用于对计算性能需求比较高的企业和组织&#xff0c;本文主要来介绍选择江苏显卡服务器租用的优势有哪些吧&#xff01; 江苏显卡服务器使用了先进的实时高速的并行计算技术和浮点计…