Scala集合

集合

集合简介

Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。

对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本,分别位于以下两个包:

  • 不可变集合:scala.collection.immutable
  • 不可变集合:scala.collection.mutable

不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于Java中的String对象。

可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于Java中的StringBuidler对象。

数组

不可变数组

val arr1 = new Array[Int](10)

[Int] 是指定可以存放的数据类型,如果希望为任意类型,则可以指定为Any

(10) 表示数组的大小,确定后不可以变化

package chapter07

object Test01_ImmutableArray {
  def main(args: Array[String]): Unit = {
    // 1. 创建数组
    val arr = new Array[Int](10)

    // 另一种创建方式
    val arr2 = Array(12, 37, 42, 58, 97)

    // 2. 访问数组中的元素
    println(arr(0))
//    println(arr(5))
    // 赋值
    arr(0) = 12
    arr(1) = 24
    println(arr(0))

    // TODO 数组的遍历
    // 普通for循环
    for(i <- 0 to arr.length - 1) {
      println(arr(i))
    }

    for (i <- arr.indices) println(arr(i))

    // 直接遍历所有元素,增强for循环
    for(elem <- arr2) {
      println(elem)
    }

    // 迭代器
    val iter = arr.iterator
    while (iter.hasNext)
      println(iter.next())

    // 调用foreach方法
    arr2.foreach((elem: Int) => println(elem))
    arr2.foreach(println) // 至简原则
    
    // 以字符串输出
    println(arr2.mkString("--"))

  }
}

可变数组

package chapter07

import scala.collection.mutable.ArrayBuffer

object Test02_ArrayBuffer {
  def main(args: Array[String]): Unit = {
    // TODO 创建可变数组
    // 默认长度为16
    val arr = new ArrayBuffer[Int]()
    val arr2 = ArrayBuffer(25, 37, 98)

    println(arr.mkString(", "))
    // 重写了toString方法,可以直接打印
    println(arr2)

    // 访问元素
//    println(arr(0)) // 此时数组越界
    println(arr2(1))
    // arr(0) = 5
    // println(arr(0))

    // TODO 添加元素
    arr += 19
    77 +=: arr
    arr.append(36)
    arr.prepend(52, 34)
    // 索引位置和数据
    arr.insert(2, 32, 59)
    println(arr)

    // TODO 删除元素
    // 索引位置
    arr.remove(2)
    // 索引位置 删除个数
    arr.remove(2, 3)
    // 删除元素的Value,如果找不到什么都不做
    arr -= 36
    println(arr)

  }
}

可变数组与不可变数组的转换

// 可变数组转换为不可变数组
val arr:ArrayBuffer[Int] = ArrayBuffer(23, 56, 98)
var array: Array[Int] = arr.toArray

// 不可变数组转换为可变数组
val arrayBuffer = array.toBuffer

多维数组

package chapter07

object Test03_MulArray {
  def main(args: Array[String]): Unit = {
    // TODO 创建二维数组
    val array = Array.ofDim[Int](2, 3)

    // 访问元素
    array(0)(2) = 19
    array(1)(0) = 25

    // 遍历
    for(i <- 0 until array.length; j <- 0 until array(i).length) {
      println(array(i)(j))
    }

    for (i <- array.indices; j <- array(i).indices) {
      print(array(i)(j) + "\t")
      if (j == array(i).length-1)
        println()
    }

    array.foreach(line => line.foreach(println))


  }
}

列表

不可变List

List默认为不可变集合

创建一个List(数据有顺序,可重复)

遍历List

List增加数据

集合间合并:将一个整体拆分成一个一个的个体,成为扁平化

去指定数据

空集合Nil

package chapter07

import scala.+:

object Test04_List {
  def main(args: Array[String]): Unit = {
    // TODO 创建List
    // 通过List伴生对象的apply方法创建
    val list = List(23, 65, 87)

    // TODO 访问元素
    println(list(1))
    list.foreach(item => println(item))

    // TODO 添加元素
    val newList = list :+ 10
    val newList2 = 10 +: list
    println(newList)
    println(newList2)
    println("=======================")

    val newList3 = list.::(51)

    // 通常上述的这种操作的使用场景
    // 我们可以在一个空集合后面添加元素
    val list2 = Nil.::(13)
    // 但是这样使用看上去还是没什么用
    // 所以有了下边的方式,将想要的数字生成一个列表
    val list3 = 13 :: Nil
    val list4 = 14 :: 53 :: -32 :: Nil

    // TODO 合并列表
    // 扁平化处理
    val list5 = list ::: list4
    println(list5)

    val list6 = list ++ list4
    println(list6)
  }
}

可变

package chapter07

import scala.collection.mutable.ListBuffer

object Test05_ListBuffer {
  def main(args: Array[String]): Unit = {
    // TODO 创建可变列表
    val list: ListBuffer[Int] = new ListBuffer[Int]()
    val list2 = ListBuffer(12, 53, 75)
    println(list)
    println(list2)

    // TODO 添加元素
    list.append(15, 62)
    println("list =>" + list)
    list2.prepend(32, 25, 64)
    println("list2 => " + list2)
    // 指定位置添加
    list.insert(19, 22)
    println("list =>" + list)

    // list += 32 += 21
    31 +=: 16 +=: list += 32 += 21
    println("list => " + list)

    // 合并List
    val list3 = list ++ list2
    println("list3 => " + list3)

    list ++= list2
    println(list)

    // TODO 修改元素
    list2(2) = 80
    list2.update(0, 30)
    println(list2)

    // TODO 删除元素
    list2.remove(2)
    list2 -= 25
    println(list2)
    
  }
}

Set集合

默认情况下,Scala使用的是不可变集合。如果你想使用可变集合,需要引用scala.collection.mutable.Set包

不可变Set

Set默认是不可变集合,数据无序

数据不可重复

遍历集合

package chapter07

object Test06_ImmutableSet {
  def main(args: Array[String]): Unit = {
    // TODO 创建Set
    println("----------创建Set----------")
    val set = Set(13, 23, 53, 12, 13, 23, 78)
    println("set => " + set)

    // TODO 添加元素
    println("----------添加元素----------")
    val set2 = set.+(20)
    val set3 = set + 30
    println("set2 => " + set2)
    println("set3 => " + set3)

    // TODO 合并集合
    // 相同的数据会进行去重,不同的数据保存
    println("----------合并Set----------")
    val set4 = Set(19, 13, 23, 53, 67, 99)
    val set5 = set ++ set4
    println("set5 => " + set5)

    // TODO 删除元素
    println("----------删除元素----------")
    val set6 = set -12
    println("set6 => " + set6)


  }
}

可变Set

package chapter07

import scala.collection.mutable.Set

object Test07_MutableSet {
  def main(args: Array[String]): Unit = {
    // TODO 创建Set
    println("----------创建Set----------")
    val set: Set[Int] = Set[Int](13,23,53,12,13,23,78)
    println("set => " + set)

    // TODO 添加元素
    println("----------添加元素----------")
    set += 11
    println("set => " + set)
    val flag = set.add(20)
    println("set => " + set)
    println("flag =>" + flag)

    // TODO 删除元素
    println("----------删除元素----------")
    set -= 13
    println("set => " + set)

    val removeFlag = set.remove(2)
    println("set => " + set)
    println("removeFlag => " + removeFlag)

    // TODO 合并Set
    println("----------合并Set----------")
    val set2 = Set(13, 12, 13, 27, 28, 29)
    val set3 = set ++ set2
    println("set =>" + set)
    println("set2 => " + set2)
    println("set3 => " + set3)

    set ++= set2
    println("set =>" + set)
    println("set2 => " + set2)
    
  }
}

Map集合

Scala中的Map和Java类似,也是一个散列表,他存储的内容也是键值对映射

不可变Map

不可变的Map集合中不可以增加元素。

package chapter07

object Test08_ImmutableMap {
  def main(args: Array[String]): Unit = {
    // TODO 创建Map
    println("----------创建Map----------")
    val map: Map[String, Int] = Map("Hello" -> 4, "World" -> 2)
    println(map)
    println(map.getClass)

    // TODO 遍历元素
    println("----------遍历元素----------")
    map.foreach(println)
    map.foreach((kv: (String, Int)) => println(kv))

    // TODO 取map中所有的key和value
    println("----------取map中所有的key和value----------")
    for (key <- map.keys) {
      println(s"${key} ---> ${map.get(key).get}")
    }

    // TODO 访问某一个key的value
    println(map.get("Hello").get)
    // 推荐写法
    println(map.getOrElse("World", 0))
    println(map.getOrElse("Nothing", 0))

  }
}

可变Map

package chapter07

import scala.collection.mutable.Map

object Test09_MutableMap {
  def main(args: Array[String]): Unit = {
    val map:Map[String, Int] = Map("Hello" -> 4, "World" -> 2)

    // TODO 添加元素
    println("----------添加元素----------")
    map.put("Scala", 2)
    println(map)

    // 使用符号添加
    map += (("Spark", 3))
    println(map)

    // TODO 删除元素
    println("----------删除元素----------")
    map.remove("Hello")

    map -= "Spark"
    println(map)

    // TODO 修改元素
    println("----------修改元素----------")
    map.update("Scala", 3)
    println(map)

    // TODO 合并两个Map
    println("----------合并两个Map----------")
    val map2 = Map[String, Int]("Hello" -> 20, "aaa" -> 32)
    map ++= map2
    // map2会覆盖map中重复的值
    println(map)
  }
}

元组

元组也是可以理解为一个容器,可以存放各种相同或者不同类库的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。

元组最大只能有22个元素。

package chapter07

object Test10_Tuple {
  def main(args: Array[String]): Unit = {
    // TODO 创建元组
    val tuple: (String, Int, Char, Boolean) = ("hello", 100, 'a', true)
    println(tuple)

    // TODO 访问数据
    println(tuple._1)
    println(tuple._2)
    println(tuple.productElement(2))

    // TODO 遍历元组数据
    for (elem <- tuple.productIterator) {
      println(elem)
    }
    
    // TODO 嵌套元组
    val mulTuple = (12, 0.3, "hello", ("haha", "scala", 23), true)
    println(mulTuple._4._1)
  }
}

集合常用函数

基本属性和常用操作

package chapter07

object Test11_CommonOperation {
  def main(args: Array[String]): Unit = {
    val list = List(1,3,5,7,2,89,100)
    val set = Set(23,34,423,75)

    // 获取集合长度
    println(list.length)

    // 获取集合大小
    println(list.size)
    println(set.size)

    // 循环遍历
    for(elem <- list) {
      print(elem + "\t")
    }
    println()

    for (elem <- set) {
      print(elem + "\t")
    }
    println()

    // 迭代器
    for (elem <- set.iterator) print(elem + "\t")
    println()

    // 生成字符串
    println(list)

    // 是否包含
    println(list.contains(23))
  }
}

衍生集合

package chapter07

object Test12_DerivedCollection {
  def main(args: Array[String]): Unit = {
    val list = List(1,3,5,7,2,89,100)
    val list2 = List(3, 89, 32, 6, 5, 2)
    println(list)

    // 获取集合的第一个元素
    println(list.head)

    // 获取除了集合第一个元素外所有的元素
    println(list.tail)

    // 集合初始数据(不包含最后一个)
    println(list.init)

    // 获取集合的最后一个元素
    println(list.last)

    // 反转
    println(list.reverse)

    // 取前(后)n个元素
    println(list.take(3))
    println(list.takeRight(3))

    // 去掉前(后)n个元素
    println(list.drop(3))
    println(list.dropRight(1))

    // 并集
    val union = list.union(list2)
    println("union =>" + union)
    println(list:::list2)
    // 如果是set做并集,则会去重

    // 交集
    val intersection = list.intersect(list2)
    println("intersection =>" + intersection)

    // 差集
    val diff1 = list.diff(list2)
    val diff2 = list.diff(list)
    println("diff1 => " + diff1)
    println("diff2 => " + diff2)

    // 拉链
    println("zip => " + list.zip(list2))

    println("--------------------")
    // 滑窗
    for (elem <- list.sliding(3)) {
      println(elem)
    }

    println("--------------------")
    for(elem <- list2.sliding(3, 2))
      println(elem)
  }
}

集合计算初级函数

package chapter07

object Test13_SimpleFunction {
  def main(args: Array[String]): Unit = {
    val list=  List(5,1,8,2,-3,4)
    val list2 = List(("a", 3), ("b", 5), ("c", 9), ("d", 2), ("e", 6))

    // 求和
    val sum = list.sum
    println(sum)

    // 求乘积
    println(list.product)

    // 最大值
    println(list.max)
    println(list2.maxBy((tuple: (String, Int)) => tuple._2))
    // 简化
    println(list2.maxBy(_._2))

    // 最小值
    println(list.min)
    println(list2.minBy(_._2))

    // 排序
    val sortedList = list.sorted
    println(sortedList)

    // 从大到小逆序排列
    // 传入一个隐式参数
    val sortedListDesc = list.sorted(Ordering[Int].reverse)
    println(sortedListDesc)

    println(list2.sortBy((tuple:(String, Int)) => tuple._2)(Ordering[Int].reverse))

    // sortWith
    println(list.sortWith((a: Int, b: Int) => { a < b }))
    // 简化
    println(list.sortWith(_ < _))
    println(list.sortWith(_ > _))
  }
}

集合计算高级函数

package chapter07

object Test14_HighLevelFunction_Map {
  def main(args: Array[String]): Unit = {
    val list = List(1,2,3,4,5,6,7)

    // TODO 过滤
    // 选取偶数
    list.filter( (elem:Int) => {elem % 2 == 0} )
    println(list.filter(_%2==0))

    // TODO 转化映射map
    // 把集合每个数*2
    list.map((elem: Int) => {elem * 2})

    // TODO 扁平化
    val nestedList: List[List[Int]] = List(List(1,23,5), List(6,7,8,9), List(4,5))

    println(nestedList.flatten)

    // 扁平映射
    // 将一组字符串进行分词,并保存成单词的列表
    val strings: List[String] = List("Hello world", "Hello Scala", "Hello Java")
    // 1.分词
    val splitList: List[Array[String]] = strings.map(string => { string.split(" ")})
    println(splitList)
    // 扁平化
    val flattenList = splitList.flatten
    println(flattenList)

    // 这样的步骤看着有点复杂,所以引出我们的扁平化操作
    val flattenMapList = strings.flatMap(_.split(" "))
    println(flattenMapList)

    // TODO 分组操作
    // 分成奇偶两组
    val groupMap = list.groupBy( _ % 2 == 0 )
    
    val groupMap2 = list.groupBy(data => if (data % 2 == 0) "偶数" else "奇数" )
  }
}
package chapter07

object Test15_HighLevelFunction_Reduce {
  def main(args: Array[String]): Unit = {
    val list= List(1,2,3,4,5)
    // 归约
    // reduce
    println(list.reduce( _ + _ ))

    println(list.reduceRight(_ - _)) // 1 - ( 2 - ( 3 - ( 4 - 5) ) )

    // fold
    println(list.fold(10)( _ + _))

    println(list.foldRight(10)( _ - _ )) // 1 - ( 2 -( 3 - ( 4 - (5 - 10) ) ))
  }
}
原文地址:https://www.cnblogs.com/Gazikel/p/15779405.html