首页 > 其他分享 >Scala 集合(上)

Scala 集合(上)

时间:2024-04-17 18:55:55浏览次数:26  
标签:arr val Scala list println 数组 集合 Array

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.iterator
        while (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 :+ 3
        println(r1.mkString(", "))
        // +: 在数组的头部来新添元素,构成一个新的数组
        val r2 = arr.+:(3)
        println(r2.mkString(", "))
        val r3 = 3 +: arr
        println(r3.mkString(", "))
        val r4 = 4 +: arr :+ 3
        println(r4.mkString(", "))
    
        // 应用四:数组合并
        val nums1 = Array(1, 2, 3, 4, 5)
        val nums2 = Array(6, 7, 8, 9)
        // 方式一:通过++合并
        val v1 = nums1 ++ nums2
        println(v1.mkString(", "))
        // 方式二: ++: 或者 :++
        // ++:等价于++
        val v2 = nums1 ++: nums2
        println(v2.mkString(", "))
        val v3 = nums1 :++ nums2
        println(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.reverse
        println(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
              // 剩余猴子数量-1
              n -= 1
              // 下一只猴子重新报数
              i = 0
            }
            // 报数+1
            i += 1
          }
          // 下一只猴子准备
          index += 1
          if (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 = {
    
        // 定义方式
        // 方式一:创建了可变数组,初始大小为0
        val r1 = new ArrayBuffer[Int]
        r1.+=(5)
        r1 += 3
        println(r1)
        // 方式二:创建可变数组,指定初始大小
        val r2 = new ArrayBuffer[Int](3)
        r2 += 4
        r2 += 2
        r2 += 5
        r2 += 7
        println(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 += 9
        arr.append(10)
        println(arr)
        // 在头部添加元素
        arr.prepend(2)
        println(arr)
        1 +=: arr
        println(arr)
        // 插入元素
        arr.insert(2, 11)
        println(arr)
        // 修改元素
        arr(0) = 0
        println(arr)
        arr.update(1, 3)
        println(arr)
        // 删除指定下标上的元素
        arr.remove(0)
        println(arr)
        // 删除元素3
        // 删除指定的元素(第一次出现)
        arr -= 3
        println(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.toArray
    println(arr)

    // 不可变数组 -> 可变数组
    val array = Array[Int](1, 2, 3, 4, 5)
    val buffer = array.toBuffer
    println(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) = 3
        println(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 = {
    
        /*
        1
        1 1
        1 2 1
        1 3 3 1
        1 4 6 4 1
        ...
         */
        // 获取整数n
        val 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) {
            // 每一行第一个或者最后一个元素是1
            if (j == 0 || j == i) arr(i)(j) = 1
            else 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 :: list
        println(list3)
    
        // 方式三:
        // Nil是List的子类,表示一个空列表
        val list4 = Nil
        println(list4)
    
        // 方式四:
        val list5 = 1 :: 2 :: 3 :: 4 :: Nil
        println(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 :+ 6
        val r1 = list.:+(6)
        println(r1)
        // 在头部追加元素
        // 从右向左计算
        val r2 = 1 +: list
        // val r2 = list.+:(1)
        // 当出现:的时候,:对着谁就从谁开始计算
        // 如果两边都有:,那么从右向左计算
        // 错误的写法:list +: 1
        println(r2)
        // 或者
        // val r3 = list.::(1)
        val r3 = 1 :: list
        // list :: 1
        println(r3)
        // 构建了列表
        // 从右到左:先构建空列表List(),然后头部拆入5,在插入4
        val r4 = 1 :: 2 :: 3 :: 4 :: 5 :: List()
        // 等价于
        val r5 = 1 :: 2 :: 3 :: 4 :: 5 :: Nil
        println(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 ++ list2
        println(r1)
        val r2 = list1 ++: list2
        println(r2)
        val r3 = list1 :++ list2
        println(r3)
        val r4 = list1.concat(list2)
        println(r4)
        val r5 = list1 ::: list2
        println(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 += 4
        println(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 += 4
        list append 7
        println(list)
        // 在头部插入元素
        list prepend 0
        // list.+=:(2)
        2 +=: list
        println(list)
        // 在指定下标位置上插入元素
        list.insert(3, 6)
        println(list)
        // 修改指定位置上的元素
        list(2) = 10
        list.update(3, 12)
        println(list)
        // 删除指定下标位置上的元素
        list.remove(0)
        println(list)
        // 删除指定的元素(第一个)
        list -= 3
        println(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 ++ list2
        println(r1)
        // 要求:将list2中的数据合并到list1中
        list1 ++= list2
        println(list1)
        // 获取list1中有而list3中没有的数据 - 差集
        val list3 = ListBuffer[Int](1, 3, 5, 7)
        list1 --= list3
        println(list1)
    
      }
    
    }
    

标签:arr,val,Scala,list,println,数组,集合,Array
From: https://www.cnblogs.com/wzzwyh/p/18141508

相关文章

  • Scala h集合(下)
    Scala集合字符串Scala中字符串同样分为可变字符串和不可变字符串,不可变字符串使用String来定义,可变字符串使用的是StringBuilder来定义packagecom.fesco.stringobjectStringDemo{defmain(args:Array[String]):Unit={//可变字符串//Scala中既然将......
  • 集合幂级数 ln exp
    写的时候有个地方忘取模调了半天【流汗】先和子集卷积一样处理出size那一维,先对集合幂级数那一维fmt,然后在形式幂级数那一维作\(\mathcal{O}(n^2)\)的暴力ln,exp。写的时候遇到的坑点是集合幂级数那一维的范围其实是\([0,n]\)而不是\([0,n-1]\)。voidfmt(int*f,int......
  • Scala集合
    概述集合本质上就是一个用于存储1个到多个数据的容器。在Scala中,集合可以分为三大类:Seq(序列),Set(集合)和Map(映射)。基于这三大类,衍生出来众多的子类序列:元素有序可重复集合:元素无序不可重复映射:键值对结构数据在Scala中,所有的集合都混入了Iterable特质,意味着所有......
  • 说说你对集合的理解?常见的操作有哪些?
    一、是什么集合(Set),指具有某种特定性质的事物的总体,里面的每一项内容称作元素在数学中,我们经常会遇到集合的概念:有限集合:例如一个班集所有的同学构成的集合无限集合:例如全体自然数集合在计算机中集合道理也基本一致,具有三大特性:确定性:于一个给定的集合,集合中的元素是确定......
  • list集合的排序
    list集合的排序使用常用的sort方法排序和stream流的方式排序packagecom.liucy.meiriyilian.sort;importjava.util.ArrayList;importjava.util.Collections;importjava.util.Comparator;importjava.util.List;importjava.util.stream.Collectors;/***@Authorli......
  • day08_我的Java学习笔记 (String类、ArrayList集合类)
    常用API(String、ArrayList)什么是APIAPI文档下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html1.String简单介绍【补充】:为什么java数据类型String是大写?1.1String类概述1.2String类创建对象的2种方式1.3String......
  • day09_我的Java学习笔记 (ATM系统_理解并学会使用break、return、continue、Random、S
    ATM系统1.项目介绍与功能演示1.1系统准备、首页设计Account.java每个用户的账户信息都是一个对象,需要提供账户类。01.在Account类中定义系统相关的属性信息(卡号、姓名、密码、余额、取现额度)02.定义Getter和Setter方法03.定义有参构造器04.定义无参构造......
  • ES6集合操作
    <!DOCTYPEhtml><html><head> <metacharset="utf-8"> <metaname="viewport"content="width=device-width,initial-scale=1"> <title>ES6数组</title></head><body> <scrip......
  • 8.集合、泛型、枚举、注解、反射
    第八章【集合、泛型、枚举、注解、反射】一、集合1、概述集合是JavaAPI中提供的一种容器工具,可以用来存储多个数据。集合框架中主要有三个要素组成:接口实现类数据结构集合中不可以存放基本类型集合按照其存储结构可以分为两大类:java.util.Collection 单值存放......
  • redis为什么一定要用跳表实现有序集合,却不用平衡树,红黑树或者B+树呢?
    平衡树vs跳表平衡树必须满足所有节点的左右子树高度差不超过1,也就是平衡因子范围为[-1,1]。但是对于范围查询来说,利用平衡树通过中序遍历达到和跳表一样的效果,但是平衡树的每一次插入或者删除操作都需要保证整棵树的绝对平衡,只要不平衡就会通过旋转的方式来重新保持平衡,这个过......