Scala h集合(下)

news/发布时间2024/5/5 1:12:07

Scala

集合

字符串

  1. Scala中字符串同样分为可变字符串和不可变字符串,不可变字符串使用String来定义,可变字符串使用的是StringBuilder来定义

    package com.fesco.stringobject StringDemo {def main(args: Array[String]): Unit = {// 可变字符串// Scala中既然将字符串看作是集合中的成员,那么字符串其实就是字符的集合val str: StringBuilder = new StringBuilder("abc")str += 'a'println(str)// 产生一个新的字符串val r1 = str.+("abc")println(str)println(r1)// 将结果转化为一个ArrayBuffer返回val r2 = str.:+('c')println(str)println(r2)str.++=("abc")println(str)}}
    

序列(Seq)

  1. 数组、列表、字符串都属于序列的子类

  2. 序列分为可变序列和不可变序列。不可变序列分为两大类:

    1. IndexedSeq:索引序列,支持通过索引来快速定位元素的位置,包含StringArrayVectorRange
    2. LinearSeq:线性序列,除了支持索引的功能以外,还有头和尾的概念,包含ListQueueStack
  3. a to b还是a until b返回就是一个Range对象

    // a to b 本质上就是返回了一个Range集合
    // for (i <- 1 to 10) println(i)
    // 实际上底层是
    val range = Range(1, 10)
    for (i <- range) println(i)
    
  4. Seq本身是一个特质,无法直接构建对象,同时伴生对象中也没有提供用于获取Seq对象的方法

  5. Seq的基本操作

    1. 索引和长度

      package com.fesco.seqobject SeqDemo {def main(args: Array[String]): Unit = {val list = List[Int](2, 4, 1, 5, 7)val arr = Array[Int](3, 5, 4, 1, 8, 0)// 通过指定下标来获取元素println(list(2))// 获取长度/元素个数println(list.length)println(list.size)println(arr.size)// 索引范围// 0 ~ list.length-1val indices: Range = list.indicesprintln(indices)// 遍历序列for (i <- list.indices) println(list(i))// isDefinedAt:判断下标是否在indices范围内println(list.isDefinedAt(3))// 等价于println(3 < list.length && 3 > 0)// a lengthCompare b:a的长度大于b,返回1;a的长度小于b返回-1;a的长度等于b,返回0println(list.lengthCompare(arr))println(list.length == arr.length)}}
      
    2. 索引搜索

      package com.fesco.seqobject SeqDemo2 {def main(args: Array[String]): Unit = {val list = List[Int](3, 2, 1, 5, 7, 5, 4, 9, 8)// indexOf:获取指定元素在序列中第一次出现的下标println(list.indexOf(5))// lastIndexOf:获取指定元素在序列中最后一次出现的下标println(list.lastIndexOf(5))// indexOfSlice:子序列在序列中第一次出现的下标val sub = List[Int](4, 9)println(list.indexOfSlice(sub))// lastIndexOfSlice:子序列在序列中最后一次出现的下标println(list.lastIndexOfSlice(sub))// indexWhere:指定条件,获取满足条件的第一个元素出现的下标// 在序列中,大于5的元素第一次出现的下标// 默认从第0为开始寻找// list.indexWhere(x => x > 5)println(list.indexWhere(_ > 5))// 从指定下标开始向后寻找println(list.indexWhere(_ > 5, 5))// 根据开头过滤val languages = List[String]("Java", "Python", "Perl", "Scala", "Ruby", "Kotlin", "Pascal")println(languages.indexWhere(_.startsWith("P")))// prefixLength:已过时,推荐使用segmentLength。不满足条件的元素,第一次出现的下标// println(list.prefixLength(_ > 5))println(list.segmentLength(_ > 5))}}
      
    3. 增加/更新

      package com.fesco.seqobject SeqDemo3 {def main(args: Array[String]): Unit = {val list = List[Int](3, 2, 1, 5, 7, 9, 8)// 尾部追加val r1 = list :+ 4println(r1)// 头部追加val r2 = 3 +: listprintln(r2)// 扩充序列,将序列的长度扩为10val r3 = list.padTo(10, 0)println(r3)// 更新数据val r4 = list.updated(2, 4)println(r4)// list(2) = 4只支持可变序列// patch(from, 子序列, 替换长度):从序列的第from下标开始,替换指定个数的元素,替换为子序列中的元素val v = List[Int](2, 4, 6)val r5 = list.patch(3, v, 3)println(r5)}}
      
    4. 排序

      package com.fesco.seqobject SeqDemo4 {def main(args: Array[String]): Unit = {// 对元素进行自然排序val list = List[Int](3, 2, 1, 5, 7, 9, 8)val r1 = list.sortedprintln(r1)val s1 = new Student("Amy", 15, 92)val s2 = new Student("Bob", 13, 85)val s3 = new Student("Tom", 14, 78)val s4 = new Student("Sam", 16, 91)val s5 = new Student("Tony", 17, 65)val s6 = new Student("Eden", 16, 72)val s7 = new Student("Hack", 15, 78)val students = List[Student](s1, s2, s3, s4, s5, s6, s7)// 按照学生姓名排序// 根据元素中的某一个属性来排序// students.sortBy(s => s.name)val namedStudents = students.sortBy(_.name)println(namedStudents)//  规则:按照分数进行降序排序,如果分数相同,则按照年龄升序println("=" * 50)val r2 = students.sortWith((s1, s2) => if (s1.score != s2.score) s1.score > s2.score else s1.age < s2.age)println(r2)}}class Student(val name: String, val age: Int, val score: Int) {override def toString: String = s"{name:$name, age:$age, score:$score}\n"
      }
      
    5. 判断

      package com.fesco.seqobject SeqDemo5 {def main(args: Array[String]): Unit = {val list = List[Int](1, 2, 3, 4, 5)val sub = List[Int](1, 2)// startsWithprintln(list.startsWith(sub))// endsWithprintln(list.endsWith(sub))// 判断是否包含了指定元素println(list.contains(3))// 判断是否包含指定子列println(list.containsSlice(sub))val number = 1 :: 2 :: 3 :: 4 :: 5 :: Nilval twice = 2 :: 4 :: 6 :: 8 :: 10 :: Nil// 判断twice中的元素是否是number中对应位置上元素的2倍// number.corresponds(twice)((x, y) => x * 2 == y)println(number.corresponds(twice)(_ * 2 == _))}}
      
    6. 多序列操作

      package com.fesco.seqobject SeqDemo6 {def main(args: Array[String]): Unit = {val list1 = List[Int](2, 4, 6, 8, 10)val list2 = List[Int](1, 2, 4, 8, 16, 32)// 并集 - a ∪ b,将a和b的数据放到一起val r1 = list1 ++: list2println(r1)val r2 = list1 :++ list2println(r2)val r3 = list1 concat list2println(r3)val r4 = list1 ::: list2println(r4)val r5 = list1 union list2println(r5)// 交集 - a ∩ b,获取a和b都有的数据val r6 = list1 intersect list2println(r6)// 差集 - a有b没有的val r7 = list1 diff list2println(r7)// 去重val r8 = r1.distinctprintln(r8)}}
      

集合(Set)

不可变集合(Set)

  1. 注意:在Scala中,无论是可变集合还是不可变集合,都是使用Set来定义,区别是可变集合是scala.collection.mutable.Set,不可变集合是scala.collection.immutable.Set

  2. 定义格式

    package com.fesco.setobject SetDemo {def main(args: Array[String]): Unit = {// 不可变集合Set本身是一个特质,就意味着无法直接创建对象// 方式一:创建空集合val set: Set[String] = Set.empty[String]println(set)// 方式二:// 无序不可重复val set2: Set[Int] = Set[Int](2, 4, 6, 8)println(set2)}}
    
  3. 基本操作

    package com.fesco.setobject SetDemo2 {def main(args: Array[String]): Unit = {val set = Set[Int](1, 3, 5, 7, 9)// 添加元素val r1 = set + 2println(r1)// 删除元素val r2 = set - 3println(r2)// 并集val set2 = Set[Int](2, 4, 6, 8)val r3 = set ++ set2println(r3)val r4 = set union set2println(r4)val r5 = set concat set2println(r5)val r10 = set | set2println(r10)// 差集val set3 = Set[Int](1, 2, 3, 4)val r6 = set -- set3println(r6)val r7 = set diff set3println(r7)val r11 = set &~ set3println(r11)// 交集val r8 = set intersect set3println(r8)val r9 = set & set3println(r9)// 遍历set.foreach(println)}}
    

可变集合(Set)

  1. 可变集合依然使用Set来定义

    val set = mutable.Set[Int]()
    
  2. 基本操作

    package com.fesco.setimport scala.collection.mutableobject SetDemo3 {def main(args: Array[String]): Unit = {// 创建可变集合对象val set = mutable.Set[Int]()println(set)// 添加元素set += 7println(set)set add 8println(set)// 删除元素set -= 7println(set)set remove 8println(set)// 合并集合val set1 = mutable.Set[Int](5, 5, 4, 7, 8, 9)val set2 = mutable.Set[Int](2, 4, 6, 8, 10)set1 ++= set2println(set1)// 差集val set3 = mutable.Set[Int](5, 4, 7, 8, 9)val set4 = mutable.Set[Int](2, 4, 6, 8, 10)set3 --= set4println(set3)}}
    

映射(Map)

不可变映射

  1. 注意:Scala中,可变映射和不可变映射都是通过Map来定义。默认使用的是不可变映射

  2. Map本身是一个特质,无法直接创建对象,所以使用的是伴生对象

    package com.fesco.mapobject MapDemo {def main(args: Array[String]): Unit = {// Map存储的是键值对,所以泛型需要指定2个// 定义的时候就需要给定键值对// 方式一val map = Map[String, Int]("Amy" -> 85, "Bob" -> 74, "Cindy" -> 63, "David" -> 59, "Evan" -> 60)println(map)// 方式二val map2 = Map[String, Int](("Frank", 15), ("Grace", 24), ("Henry", 36), ("Iran", 44))println(map2)}}
    
  3. 基本操作

    package com.fesco.mapobject MapDemo2 {def main(args: Array[String]): Unit = {val map = Map[String, Int]("Jack" -> 85, "Kathy" -> 79, "Lily" -> 64, "Mark" -> 58, "Nelson" -> 84)// 添加键值对val r1 = map + ("Odersky" -> 75)println(r1)val r2 = map + (("Peter", 74))println(r2)// 如果添加的键值对的键已经存在,那么对应的值来进行替换val r3 = map + ("Lily" -> 81)println(r3)// 移除指定的键对应的键值对val r4 = map - "Nelson"println(r4)// 获取指定键对应的值// 为了防止空指针异常,将get函数的返回值封装成了Option类型// 如果有实际值,那么可以从Option中获取到实际值// 如果没有实际值,那么会从Option获取到Noneval r5:Option[Int] = map get "Mark"val r6:Option[Int] = map get "Rose"// println(if(!r5.isEmpty) r5.get else r5)println(if(r5.isDefined) r5.get else r5)// println(if(!r6.isEmpty) r6.get else r6)println(if(r6.isDefined) r6.get else r6)// 获取指定键对应的值,如果键存在,那么返回实际值;如果键不存在,返回指定的值val r7 = map.getOrElse("Thomas", 0)println(r7)}}
    

可变映射

  1. 可变映射也是通过Map来定义

  2. 基本操作

    package com.fesco.mapimport scala.collection.mutableobject MapDemo3 {def main(args: Array[String]): Unit = {val map = mutable.Map[String, Int]()// 添加元素map.put("Adair", 84)map.put("Bruce", 58)map.put("Bruce", 67)println(map)map += ("Cindy" -> 72)map += (("Danny", 72))println(map)// 修改指定的键对应的值map.update("Cindy", 85)map("Adair") = 96println(map)// 获取指定的键对应的值// get函数将结果封装成Option[Some]对象// Option[Int] => Option[Some]val r1: Option[Int] = map.get("Bruce")println(r1)val r2: Int = map("Bruce")println(r2)val r3 = map.getOrElse("Fed", 0)println(r3)// 删除指定键对应的值map remove "Bruce"map -= "Adair"println(map)}}
    

遍历映射

  1. 键的遍历:遍历所有的键,通过键来获取值

    package com.fesco.mapobject MapDemo4 {def main(args: Array[String]): Unit = {val map = Map[String, Int]("Peter" -> 15, "Tony" -> 17, "Simon" -> 16, "Kohn" -> 18, "Lucy" -> 20, "Vincent" -> 21, "William" -> 20)// 键的遍历// 方式一:keySet,将所有的键放入一个Set中返回val keySet: Set[String] = map.keySetfor (key <- keySet) println(s"key:$key, value:${map(key)}")// 方式二:keys,将所有的键放入一个Iterable中返回println("=" * 100)val keys: Iterable[String] = map.keysfor (key <- keys) println(s"key:$key, value:${map(key)}")// 方式三:keysIterator,将所有的键放入一个Iterator中返回println("=" * 100)val keysIterator: Iterator[String] = map.keysIteratorfor (key <- keysIterator) println(s"key:$key, value:${map(key)}")}}
    
  2. 获取所有的值

    package com.fesco.mapobject MapDemo5 {def main(args: Array[String]): Unit = {val map = Map[String, Int]("Peter" -> 15, "Tony" -> 17, "Simon" -> 16, "Kohn" -> 18, "Lucy" -> 20, "Vincent" -> 21, "William" -> 20)// 获取所有的值// 方式一val values: Iterable[Int] = map.valuesfor (value <- values) println(value)// 方式二println("=" * 50)val valuesIterator: Iterator[Int] = map.valuesIteratorfor (elem <- valuesIterator) println(elem)}}
    
  3. 遍历映射

    package com.fesco.mapobject MapDemo6 {def main(args: Array[String]): Unit = {val map = Map[String, Int]("Peter" -> 16, "Tony" -> 17, "Simon" -> 16, "Kohn" -> 18, "Lucy" -> 20, "Vincent" -> 21, "William" -> 20)// 方式一:iterator,将键值对放入一个Iterator中返回val it: Iterator[(String, Int)] = map.iteratorfor (t <- it) println(s"key:${t._1}, value:${t._2}")// 方式二:直接使用增强for循环,本质上就是一个迭代过程println("=" * 50)for (t <- map) println(s"key:${t._1}, value:${t._2}")// 方式三:foreach函数println("=" * 50)map.foreach(t => println(s"key:${t._1}, value:${t._2}"))}}
    
  4. 映射中的键值对实际上就是Tuple2,Tuple2又称之为对偶元组。因此,在Scala中,Map实际上就是一个存储了多个Tuple2的数组

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

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

相关文章

golang+kafka

目录1. 安装JDK、Zookeeper、Scala、kafka2. 启动kafka3. 创建topics4. 查看topics5. 打开一个producer6. 打开一个consumer7. 测试发送和接收消息Windows下安装Kafka 1. 安装JDK、Zookeeper、Scala、kafka 安装Kafka之前,需要安装JDK、Zookeeper、Scala。Kafka依赖Zookeeper,…

Python-数字取证秘籍(三)

Python 数字取证秘籍(三)原文:zh.annas-archive.org/md5/941c711b36df2129e5f7d215d3712f03 译者:飞龙 协议:CC BY-NC-SA 4.0第六章:阅读电子邮件和获取名称的配方 本章涵盖了以下配方:解析 EML 文件查看 MSG 文件订购外卖盒子里有什么?解析 PST 和 OST 邮箱介绍 一旦计…

一个.NET内置依赖注入的小型强化版

前言 .NET生态中有许多依赖注入容器。在大多数情况下,微软提供的内置容器在易用性和性能方面都非常优秀。外加ASP.NET Core默认使用内置容器,使用很方便。 但是笔者在使用中一直有一个头疼的问题:服务工厂无法提供请求的服务类型相关的信息。这在一般情况下并没有影响,但是…

宝塔面板mysql无法启动问题如何解决

宝塔面板无法启动的问题和解决 如果你的宝塔里面的mysql无法启动了,请先看是不是以下的配置问题 1.是不是你的3306端口被占用了导致mysql无法启动 2.是不是磁盘空间不足导致的无法启动 如果都不是这些问题再继续向下看 常见问题: 1、Mysql安装好后或迁移文件后无法启动 2、My…

小程序上显示富文本

功能:富文本内容格式化、拿到富文本里的所有图片点击放大图片util.tsexport function formatRichText(html: any) { // 富文本内容格式化let arrText = html;//正则匹配不含style="" 或 style= 的img标签var regex1 = new RegExp("(i?)(\<img)(?!(.*?sty…

TPU-MLIR实现技术详细介绍

TPU-MLIR实现技术详细介绍 TPU-MLIR简介 后文假定用户已经处于docker里面的/workspace目录。 编译ONNX模型 以 yolov5s.onnx 为例, 介绍如何编译迁移一个onnx模型至BM1684X TPU平台运行。 该模型来自yolov5的官网: https://github.com/ultralytics/yolov5/releases/download/v6…