大数据学习15之Scala集合与泛型

1. 概述

        大部分编程语言都提供了数据结构对应的编程库,并称之为集合库(Collection Library),Scala 也不例外,且它还拥有以下优点:
易用:灵活组合运用集合库提供的方法,可以解决大部分集合问题
简洁:拜类型推断和函数式编程所赐,帮助程序员写出更简洁,更优雅的代码
安全:绝大部分错误都可以在编译期被发现
快速:集合类型的方法在实现时,都进行了调优,用户可以根据需求选择合适的集合
统一:Scala 的集合有非常严谨的继承体系,相似类型的集合拥有同样的一组方法,当然也有属于自己独有的方法。

2. 分类

        不可变集合:集合内的元素、长度一旦初始化完成就不可再进行更改,任何对集合的改变都将生成一个新的集合。不可变集合都在 scala.collection.immutable 这个包下,使用时无需手动导包。

        可变集合    :指的是这个集合本身可以动态改变,且可变集合提供了改变集合内元素的方法。可变集合都在scala.collection.mutable 这个包下,使用时需要手动导包。

3. 继承树

        

4. 上层接口

4.1. Traversable

4.1.1. 概述

        Traversable 是一个特质(trait),它是其他集合的父特质,它的子特质 immutable.Traversable 和 mutable.Traversable 分别是不可变集可变集合的父特质,集合中大部分通用的方法都是在这个特质中定义的。因此了解它的功能对学习其他集合类十分重要。

4.1.2转置集合

了解过线性代数的同学都知道,矩阵有一个转置的操作,在 Scala 中,可以轻松通过 transpose() 方法实现类似的效果。矩阵的转置是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引,如下图:

4.1.3. 拼接集合

        新集合=集合1++集合2 

        会创建临时集合,不推荐

        新集合=Traversable.concat(集合1, 集合2, 集合3)

        预先计算所需集合大小,生成一个集合,减少临时集合的生成。

4.1.4. 计算阶乘*

        

4.1.5. 获取元素*

4.1.6. 判断元素*

4.1.7. 聚合操作

4.1.8. 类型转换

        有时候,需要把 Traversable 集合转换成其他的集合来进行操作,例如转为 Set 集快速去重,此时就需要用到toXxx() 方法(toList, toSet, toArray, toSeq 等)。

4.1.9. 填充元素

        

4.2. Iterable

4.2.1. 概述

        Iterable 代表一个可以迭代的集合,它继承了 Traversable 特质,同时也是其他集合的父特质。最重要的是,它定义了获取迭代器 iterator 的方法: def iterator: Iterator[A] ,这是一个抽象方法,它的实现类需要实现这个方法,从而实现迭代集合并返回集合中的元素。

4.2.2. 分类

        iterator()

        foreach()

4.2.3. 遍历集合

    list.foreach(println);


    it=list.toIterator();
    while(it.hasNext()){
        println(it.next())
}

4.2.4. 分组遍历

object IterableGroupedDemo {
def main(args: Array[String]): Unit = {
// 定义一个 Iterable 集合,存储 1~13 之间的所有整数
val iterable = (1 to 13).toIterable
// 通过 grouped() 方法,对 Iterator 集合按照 5 个元素为一组的形式进行分组,遍历并打印结果
val iterator = iterable.grouped(5)
while (iterator.hasNext) {
println(iterator.next())
}
}

4.2.5. 按索引生成元组

/**
* 按索引生成元组
*/
object IterableGenerateTupleDemo {
def main(args: Array[String]): Unit = {
// 定义一个 Iterable 集合,存储"A", "B", "C", "D", "E"
val i = Iterable("A", "B", "C", "D", "E")
// 通过 zipWithIndex() 方法按照`字符串 -> 索引`生成新的集合
val result1 = i.zipWithIndex
println(s"result1 = ${result1}")
// 通过 map() 方法按照`索引 -> 字符串`生成新的集合
val result2 = result1.map(x => x._2 -> x._1)
println(s"result2} = ${result2}")
}
}

4.2.6. 判断集合是否相同

        通过 sameElements() 方法来实现该需求。

4.3. Seq

4.3.1. 概述

        Seq(Sequence)特质代表按照一定顺序排列的元素序列,序列是一种特别的可迭代集合,它的元素特点是有序(元素存取顺序一致),可重复,有索引。

4.3.2. 分类

        

4.3.3. 获取元素与长度

object SeqGetElementAndLenDemo {
def main(args: Array[String]): Unit = {
// 创建 Seq 集合,存储元素 1, 2, 3, 4, 5
val s = (1 to 5).toSeq
// 打印集合元素
s.foreach(x => println(x))
// 简化版
s.foreach(println(_))
s.foreach(println)
// 打印集合长度
println(s.size)
// 获取索引为 2 的元素
// 通过集合名(索引)的方式获取
println(s(2))
// 通过集合伴生对象的 apply 方法获取
println(s.apply(2))
}
}

4.3.4. 获取元素索引*

4.3.5. 判断集合是否包含指定元素

4.3.6. 修改元素

        

        

4.4. Set

去重;

HashSet 唯一无序;

ListSet 唯一有序(添加顺序);

TreeSet 唯一有序(自然顺序);

4.5. Map

HashMap:元素特点 Key 唯一、无序。
ListMap:元素特点 Key 唯一、有序(元素添加的顺序)。
TreeMap:元素特点 Key 唯一、排序(按自然顺序排序)。

5. 下层实现

  敲代码练习

数组 Array

元组 Tuple

列表 List

集 Set

映射 Map

迭代器 Iterator

栈 Stack

队列 Queue

6. 函数式编程

        函数式编程将计算视为数学函数的求值,强调纯函数、不可变性和高阶函数的使用。函数式编程的核心思想是将计算任务分解为函数之间的组合,以解决问题和构建软件。

内容另起;

泛型 Generics

1. 分类

1.1. 泛型集合

        

// 定义集合不指定泛型,可以随意存储sca
val list1 = List(2, 3.14, "abc", true, null)
// 定义集合指定泛型,只能存储指定类型数据
val list2 = List[Int](1, 2, 3, 4, 5)

1.2. 泛型方法

def 方法名[泛型名称](...): Unit {
}

1.3. 泛型类

/**
* 泛型类
*/
object GenericsClassDemo {
// 定义一个 Pair 泛型类,该类包含两个字段,且两个字段的类型不固定
class Pair[T](var a: T, var b: T)
case class Person(name: String, age: Int)
def main(args: Array[String]): Unit = {
// 创建不同类型的 Pair 泛型类对象,并打印
val pair1 = new Pair[Int](10, 20)
println(pair1.a, pair1.b)
val pair2 = new Pair[Person](Person("张三", 18), Person("李四", 19))
println(pair2.a, pair2.b)
}
}

1.4. 泛型特质

/**
* 泛型特质
*/
object GenericsTraitDemo {
// 定义泛型特质 Logger,该特质有一个变量 name 和 log 方法,它们都使用 Logger 特质的泛型
trait Logger[T] {
val name: T
def log(b: T)
}
// 定义单例对象 InfoLogger 继承 Logger 特质
object InfoLogger extends Logger[String] {
override val name: String = "INFO"
override def log(b: String): Unit = println(b)
}
def main(args: Array[String]): Unit = {
InfoLogger.log(s"${InfoLogger.name}:这是一条日志信息")
}
}

2. 上下界

2.1. 上界

        使用 T <: 类型 表示给类型添加一个上界,表示泛型参数必须是继承自该类型或是其类型本身。
        例如: [T <: Animal] 表示泛型 T 的数据类型必须是 Animal 类型或者 Animal 的子类型。

/**
* 上界
*/
object GenericsUpDemo {
// 定义一个 Animal 类
class Animal
// 定义一个 Cat 类,继承 Animal 类
class Cat extends Animal
// 定义一个 Tom 类,继承 Cat 类
class Tom extends Cat
// 定义一个泛型方法 demo,该方法接收一个 Array 参数
// 限定 demo 方法的 Array 元素类型只能是 Animal 或者 Animal 的子类型
def demo[T <: Cat](arr: Array[T]): Unit = {
println(arr.mkString("Array(", ", ", ")"))
}
def main(args: Array[String]): Unit = {
// 测试调用 demo 方法,传入不同元素类型的 Array
// 定义上界以后,下面这行代码会报错
//demo(Array(new Animal, new Animal))
demo(Array(new Cat, new Cat))
demo(Array(new Tom, new Tom))
}
}

2.2. 下界

        使用 T >: 类型 表示给类型添加一个下界,表示泛型参数必须是该类型的祖先类或是其类型本身。
        例如: [T >: Person] 表示泛型 T 的数据类型必须是 Person 类型或者 Person 的祖先类型。

/**
* 下界
*/
object GenericsDownDemo {
// 定义一个 Animal 类
class Animal
// 定义一个 Cat 类,继承 Animal 类
class Cat extends Animal
// 定义一个 Tom 类,继承 Cat 类
class Tom extends Cat
// 定义一个 demo 泛型方法,该方法接收一个 Array 参数
// 限定 demo 方法的 Array 元素类型只能是 Person 或者 Hero
def demo[T >: Cat](arr: Array[T]): Unit = {
println(arr.mkString("Array(", ", ", ")"))
}
def main(args: Array[String]): Unit = {
// 测试调用 demo 方法,传入不同元素类型的 Array
demo(Array(new Animal, new Animal))
demo(Array(new Cat, new Cat))
// 定义下界以后,下面这行代码会报错
//demo(Array(new Tom, new Tom))
}
}

3. 非变、协变、逆变

Spark 源代码中大量使用了协变、逆变、非变,学习该知识点对将来阅读 Spark 源码很有帮助。
非变:A 类和 B 类之间存在父子关系,泛型非变操作后两个泛型类之间不会产生任何关系。
协变:A 类和 B 类之间存在父子关系,泛型协变操作后两个泛型类之间也属于父子关系。
逆变:A 类和 B 类之间存在父子关系,泛型逆变操作后两个泛型类之间关系进行颠倒。

3.1. 语法格式

非变: Temp[T]{} 。泛型默认即是非变的。
协变: Temp[+T]{} 。
逆变: Temp[-T]{} 。

/**
* 非变、协变、逆变
*/
object GenericsVariantDemo {
class A
class B extends A
// 非变
class Temp1[T]
// 协变
class Temp2[+T]
// 逆变
class Temp3[-T]
def main(args: Array[String]): Unit = {
// 测试非变
val t1: Temp1[B] = new Temp1[B]
// 编译报错,非变操作后两个类之间不会产生任何关系
//val t2: Temp1[A] = t1
// 测试协变
val t3: Temp2[B] = new Temp2[B]
// 正常编译且运行,协变操作后两个类之间关系不发生任何改变
val t4: Temp2[A] = t3
// 测试逆变
val t5: Temp3[B] = new Temp3[B]
// 编译报错,逆变操作后两个类之间关系进行颠倒
//val t6: Temp3[A] = t5
// 以下逆变操作正常编译且运行
val t7: Temp3[A] = new Temp3[A]
val t8: Temp3[B] = t7
}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux网络——网络初识

目录 1. 认识协议 2. 协议的分层 3. OSI 七层模型 && TCP/IP 五层(四层)模型 4. 网络传输的基本流程 5. 以太网的通信原理 6. 数据的跨网络传播 7. 认识 IP 地址 ① IP 是什么 ② IP 与 MAC 的关系 ③ 为什么需要 IP 在谈及网络之前&#xff0c;我们要先对学…

数字IC后端低功耗设计实现案例分享(3个power domain,2个voltage domain)

下图所示为咱们社区T12nm A55低功耗实现项目。其实这个项目还可以根据产品的需求做一些改进。改进后项目实现的难度会大大增加。也希望通过今天的这个项目案例分享&#xff0c;帮助到今年IC秋招的同学。 芯片低功耗设计实现upf编写指南&#xff08;附低功耗项目案例&#xff0…

Ubuntu从入门到精通(一)系统安装

Ubuntu从入门到精通&#xff08;一&#xff09; 1 Ubuntu镜像选择 下载Ubuntu 20.04系统ISO镜像 安装 Ubuntu 20.04系统,就必须有 Ubuntu 20.04系统软件安装程序可以通过浏览器访问Ubuntu20.04的官方站点&#xff0c; 然后在导舰栏找划 Dowwnloads->Mirrors链接&#xff…

说说软件工程中的“协程”

在软件工程中&#xff0c;协程&#xff08;coroutine&#xff09;是一种程序运行的方式&#xff0c;可以理解成“协作的线程”或“协作的函数”。以下是对协程的详细解释&#xff1a; 一、协程的基本概念 定义&#xff1a;协程是一组序列化的子过程&#xff0c;用户能像指挥家…

【linux】进程等待与进程替换

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;linux笔记仓 目录 01.进程等待系统调用获取子进程status常用宏使用示例 02.进程替换替换函数关键点解释&#xff1a;代码详细分析execvpe 函数的使用 01.进程等待 任何子进程&#xff0c;在退出的…

认证鉴权框架SpringSecurity-5--权限管理篇

上面两篇我们重点介绍了如何在代码上集成springSecurity&#xff0c;同时完成登录认证和token认证的过程。我们直到springSecurity处理能帮我们完成认证外&#xff0c;还可以帮助我们完成权限校验的工作&#xff0c;这篇我们来重点介绍下springSecurity是如何实现鉴权的。 一、…

RK3588开发板Android12-SDK更新通知

迅为RK3588开发板Android12 SDK升级至RK的android-12.1-mid-rkr14版本 内核版本&#xff1a;升级至 5.10.160 版本&#xff0c;提供更好兼容性和性能。 rkbin 版本&#xff1a;支持最新的 1.17 版本 bin 和 1.46 版本的 bl31。

stm32教程:OLED屏显示字母、汉字、图片工程讲解

早上好啊&#xff0c;大佬们&#xff0c;今天带来的是我们 stm32系列的第一个外设——OLED&#xff0c;相信大家对于OLED都不陌生了吧&#xff0c;这个可以说每一个项目里的必需品了&#xff0c;单片机离不开OLED就像西方离不开耶路撒冷。 在生活中&#xff0c;我们见到的OLED的…

力扣 LeetCode 28. 找出字符串中第一个匹配项的下标(Day4:字符串)

解题思路&#xff1a; KMP算法 需要先求得最长相等前后缀&#xff0c;并记录在next数组中&#xff0c;也就是前缀表&#xff0c;前缀表是用来回退的&#xff0c;它记录了模式串与主串(文本串)不匹配的时候&#xff0c;模式串应该从哪里开始重新匹配。 next[ j - 1 ] 记录了 …

我与Linux的爱恋:进程间通信 匿名管道

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;Linux的学习 文章目录 匿名管道pipe 匿名管道 匿名管道&#xff08;Anonymous Pipes&#xff09;是Unix和类Unix操作系统中的一种通信机制&#xff0c;用于在两个进程之间传递数据。匿名…

Java之JDBC,Maven,MYBatis

前言 就是用来操作数据库的 1.JDBC快速入门 注意在使用前一定要导入jar包 在模块那里新建目录&#xff0c;新建lib&#xff0c;粘贴复制jar包&#xff0c;我这个jar设置的是模块有效 package test1017;import java.sql.Connection; import java.sql.DriverManager; import…

基于Matlab的碎纸片的自动拼接复原技术

碎纸片的自动拼接复原技术 摘要&#xff1a;破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。目前发现对碎纸片的拼接大部分由人工完成&#xff0c;准确率较高&#xff0c;但耗费大量人力财力及时间&#xff0c;效率很低。随着计算机技术的…

STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。

使用 STM32 设计的较为复杂的物联网项目&#xff0c;包括智能家居控制系统&#xff0c;涵盖了硬件和软件的详细设计。 一、硬件设计 微控制器&#xff1a;选择 STM32F4 系列微控制器&#xff0c;如 STM32F407ZGT6&#xff0c;具有高性能和丰富的外设资源。 传感器模块&#x…

1.7 JS性能优化

从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 域名解析 https://www.zhaowa.com > ip 1. 切HOST&#xff1f; > 浏览器缓存映射、系统、路由、运营商、根服务器 2. 实际的静态文件存放&#xff1f; 大流量 > 多个…

LPDDR4芯片学习(四)——DDR Training

一、ZQ Calibration DDR 学习时间 (Part B - 6)&#xff1a;DRAM ZQ 校正 - 知乎 (zhihu.com) 从原理上解释什么是DDR的ZQ校准&#xff1f; - 知乎 (zhihu.com) LPDDR4的训练(training)和校准(calibration)--ZQ校准(Calibration)_wonder_coole-腾讯云开发者社区 01 ZQ校准的…

pycharm分支提交操作

一、Pycharm拉取Git远程仓库代码 1、点击VCS > Get from Version Control 2、输入git的url&#xff0c;选择自己的项目路径 3、点击Clone&#xff0c;就拉取成功了 默认签出分支为main 选择develop签出即可进行开发工作 二、创建分支&#xff08;非必要可以不使用&#xf…

鸿蒙实战:页面跳转

文章目录 1. 实战概述2. 实现步骤2.1 创建项目2.2 准备图片素材2.3 编写首页代码2.4 创建第二个页面 3. 测试效果4. 实战总结 1. 实战概述 实战概述&#xff1a;本实战通过ArkUI框架&#xff0c;在鸿蒙系统上开发了一个简单的两页面应用。首页显示问候语和“下一页”按钮&…

IDEA部署AI代写插件

前言 Hello大家好&#xff0c;当下是AI盛行的时代&#xff0c;好多好多东西在AI大模型的趋势下都变得非常的简单。 比如之前想画一幅风景画得先去采风&#xff0c;然后写实什么的&#xff0c;现在你只需描述出你想要的效果AI就能够根据你的描述在几分钟之内画出一幅你想要的风景…

深入理解 Spark 中的 Shuffle

Spark 的介绍与搭建&#xff1a;从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交&#xff1a;本地与集群模式全解析-CSDN博客 Spark on YARN&#xff1a;Spark集群模式…

常用在汽车PKE无钥匙进入系统的高度集成SOC芯片:CSM2433

CSM2433是一款集成2.4GHz频段发射器、125KHz接收器和8位RISC&#xff08;精简指令集&#xff09;MCU的SOC芯片&#xff0c;用在汽车PKE无钥匙进入系统里。 什么是汽车PKE无钥匙进入系统&#xff1f; 无钥匙进入系统具有无钥匙进入并且启动的功能&#xff0c;英文名称是PKE&…