zoukankan      html  css  js  c++  java
  • Scala 集合

    集合简介

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

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

    不可变集合:scala.collection.immutable

    可变集合: scala.collection.mutable

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

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

    不可变集合继承图

    IndexedSeq 和 LinearSeq 的区别:

    (1)IndexedSeq 是通过索引来查找和定位,因此速度快,比如 String 就是一个索引集合,通过索引即可定位

    (2)LinearSeq 是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找

    可变集合继承图

    列表 List

    不可变 List

    (1)List 默认为不可变集合

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

    (3)遍历 List

    (4)List 增加数据

    (5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化

    (6)取指定数据

    (7)空集合 Nil

    object TestList {
     def main(args: Array[String]): Unit = {
     //(1)List 默认为不可变集合
     //(2)创建一个 List(数据有顺序,可重复)
     val list: List[Int] = List(1,2,3,4,3)
     
     //(7)空集合 Nil
     val list5 = 1::2::3::4::Nil
     //(4)List 增加数据
     //(4.1)::的运算规则从右向左
     //val list1 = 5::list
     val list1 = 7::6::5::list
     //(4.2)添加到第一个元素位置
     val list2 = list.+:(5)
     //(5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化
     val list3 = List(8,9)
     //val list4 = list3::list1
     val list4 = list3:::list1
     //(6)取指定数据
     println(list(0))
     //(3)遍历 List
     //list.foreach(println)
     //list1.foreach(println)
     //list3.foreach(println)
     //list4.foreach(println)
     list5.foreach(println)
     }
    }

    可变 ListBuffer

    (1)创建一个可变集合 ListBuffer

    (2)向集合中添加数据

    (3)打印集合数据

    object TestList {
     def main(args: Array[String]): Unit = {
     //(1)创建一个可变集合
     val buffer = ListBuffer(1,2,3,4)
     //(2)向集合中添加数据
     buffer.+=(5)
    buffer.append(6)
    buffer.insert(1,2)
     //(3)打印集合数据
     buffer.foreach(println)
    //(4)修改数据
    buffer(1) = 6
    buffer.update(1,7)
    //(5)删除数据
    buffer.-(5)
    buffer.-=(5)
    buffer.remove(5)
     }
    }

    Set 集合

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

    不可变 Set

    def main(args: Array[String]): Unit = {
     //(1)Set 默认是不可变集合,数据无序
     val set = Set(1,2,3,4,5,6)
     //(2)数据不可重复
     val set1 = Set(1,2,3,4,5,6,3)
     //(3)遍历集合
     for(x<-set1){
     println(x)
     }
     }

    可变 mutable.Set

    (1)创建可变集合 mutable.Set

    (2)打印集合

    (3)集合添加元素

    (4)向集合中添加元素,返回一个新的 Set

    (5)删除数据

    def main(args: Array[String]): Unit = {
     //(1)创建可变集合
     val set = mutable.Set(1,2,3,4,5,6)
     //(3)集合添加元素
     set += 8
     //(4)向集合中添加元素,返回一个新的 Set
     val ints = set.+(9)
     println(ints)
     println("set2=" + set)
     //(5)删除数据
     set-=(5)
    //(2)打印集合
     set.foreach(println)
     println(set.mkString(","))
     }

    Map 集合

    Scala 中的 Map 和 Java 类似,也是一个散列表,它存储的内容也是键值对(key-value) 映射

    不可变 Map

    (1)创建不可变集合 Map

    (2)循环打印

    (3)访问数据

    (4)如果 key 不存在,返回 0

    def main(args: Array[String]): Unit = {
     // Map
     //(1)创建不可变集合 Map
     val map = Map( "a"->1, "b"->2, "c"->3 )
     //(3)访问数据
     for (elem <- map.keys) {
     // 使用 get 访问 map 集合的数据,会返回特殊类型 Option(选项):
    有值(Some),无值(None)
     println(elem + "=" + map.get(elem).get)
     }
     //(4)如果 key 不存在,返回 0
     println(map.get("d").getOrElse(0))
     println(map.getOrElse("d", 0))
     //(2)循环打印
     map.foreach((kv)=>{println(kv)})
     }

    可变 Map

    (1)创建可变集合

    (2)打印集合

    (3)向集合增加数据

    (4)删除数据

    元组(5)修改数据

    def main(args: Array[String]): Unit = {
     //(1)创建可变集合
     val map = mutable.Map( "a"->1, "b"->2, "c"->3 )
     //(3)向集合增加数据
     map.+=("d"->4)
     // 将数值 4 添加到集合,并把集合中原值 1 返回
     val maybeInt: Option[Int] = map.put("a", 4)
     println(maybeInt.getOrElse(0))
     //(4)删除数据
     map.-=("b", "c")
     //(5)修改数据
     map.update("d",5)
    map("d") = 5
     //(2)打印集合
     map.foreach((kv)=>{println(kv)})
     }

    元组

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

    注意:元组中最大只能有 22 个元素。

    (1)声明元组的方式:(元素 1,元素 2,元素 3)

    (2)访问元组

    (3)Map 中的键值对其实就是元组,只不过元组的元素个数为 2,称之为对偶

    def main(args: Array[String]): Unit = {
     //(1)声明元组的方式:(元素 1,元素 2,元素 3)
     val tuple: (Int, String, Boolean) = (40,"bobo",true)
     //(2)访问元组
     //(2.1)通过元素的顺序进行访问,调用方式:_顺序号
     println(tuple._1)
     println(tuple._2)
     println(tuple._3)
     //(2.2)通过索引访问数据
     println(tuple.productElement(0))
     //(2.3)通过迭代器访问数据
     for (elem <- tuple.productIterator) {
     println(elem)
     }
     //(3)Map 中的键值对其实就是元组,只不过元组的元素个数为 2,称之为
    对偶
     val map = Map("a"->1, "b"->2, "c"->3)
     val map1 = Map(("a",1), ("b",2), ("c",3))
     map.foreach(tuple=>{println(tuple._1 + "=" + tuple._2)})
     }

    集合常用函数

    基本属性和常用操作

    (1)获取集合长度 (2)获取集合大小 (3)循环遍历 (4)迭代器 (5)生成字符串 (6)是否包含

    def main(args: Array[String]): Unit = {
     val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
     //(1)获取集合长度
     println(list.length)
     //(2)获取集合大小,等同于 length
     println(list.size)
     //(3)循环遍历
     list.foreach(println)
     //(4)迭代器
     for (elem <- list.itera tor) {
     println(elem)
     }
     //(5)生成字符串
     println(list.mkString(","))
     //(6)是否包含
     println(list.contains(3))
     }

    衍生集合

    (1)获取集合的头(2)获取集合的尾(不是头的就是尾) (3)集合最后一个数据 (4)集合初始数据(不包含最后一个) (5)反转 (6)取前(后)n 个元素 (7)去掉前(后)n 个元素 (8)并集 (9)交集 (10)差集 (11)拉链 (12)滑窗

     def main(args: Array[String]): Unit = {
     val list1: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
     val list2: List[Int] = List(4, 5, 6, 7, 8, 9, 10)
     //(1)获取集合的头
     println(list1.head)
     //(2)获取集合的尾(不是头的就是尾)
     println(list1.tail)
     //(3)集合最后一个数据
     println(list1.last)
     //(4)集合初始数据(不包含最后一个)
     println(list1.init)
     //(5)反转
     println(list1.reverse)
     //(6)取前(后)n 个元素
    println(list1.take(3))
     println(list1.takeRight(3))
     //(7)去掉前(后)n 个元素
     println(list1.drop(3))
     println(list1.dropRight(3))
     //(8)并集
     println(list1.union(list2))
     //(9)交集
     println(list1.intersect(list2))
     //(10)差集
     println(list1.diff(list2))
     //(11)拉链 注:如果两个集合的元素个数不相等,那么会将同等数量的数据进
    行拉链,多余的数据省略不用
     println(list1.zip(list2))
     //(12)滑窗
     list1.sliding(2, 5).foreach(println)

    集合计算简单函数

    (1)求和 (2)求乘积 (3)最大值 (4)最小值 (5)排序

    def main(args: Array[String]): Unit = {
     val list: List[Int] = List(1, 5, -3, 4, 2, -7, 6)
     //(1)求和
     println(list.sum)
    //(2)求乘积
     println(list.product)
     //(3)最大值
     println(list.max)
     //(4)最小值
     println(list.min)
     //(5)排序
     // (5.1)按照元素大小排序
     println(list.sortBy(x => x))
     // (5.2)按照元素的绝对值大小排序
     println(list.sortBy(x => x.abs))
     // (5.3)按元素大小升序排序
    println(list.sortWith((x, y) => x < y))
    // (5.4)按元素大小降序排序
     println(list.sortWith((x, y) => x > y))

    (1)sorted 对一个集合进行自然排序,通过传递隐式的 Ordering

    (2)sortBy 对一个属性或多个属性进行排序,通过它的类型。

    (3)sortWith 基于函数的排序,通过一个 comparator 函数,实现自定义排序的逻辑。

    集合计算高级函数

    (1)过滤 遍历一个集合并从中获取满足指定条件的元素组成一个新的集合

    (2)转化/映射(map将集合中的每一个元素映射到某一个函数

    (3)扁平化

    (4)扁平化+映射 注:flatMap 相当于先进行 map 操作,在进行 flatten 操作 集合中的每个元素的子元素映射到某个函数并返回新集合

    (5)分组(group) 按照指定的规则对集合的元素进行分组

    (6)简化(归约)

    (7)折叠

    def main(args: Array[String]): Unit = {
     val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
     val nestedList: List[List[Int]] = List(List(1, 2, 3), List(4, 
    5, 6), List(7, 8, 9))
     val wordList: List[String] = List("hello world", "hello 
    atguigu", "hello scala")
     //(1)过滤
     println(list.filter(x => x % 2 == 0))
     //(2)转化/映射
     println(list.map(x => x + 1))
     //(3)扁平化
     println(nestedList.flatten)
     //(4)扁平化+映射 注:flatMap 相当于先进行 map 操作,在进行 flatten
    操作
     println(wordList.flatMap(x => x.split(" ")))
     //(5)分组
     println(list.groupBy(x => x % 2))

    Reduce 方法

    Reduce 简化(归约) :通过指定的逻辑将集合中的数据进行聚合,从而减少数据,最 终获取结果。

    def main(args: Array[String]): Unit = {
     val list = List(1,2,3,4)
     // 将数据两两结合,实现运算规则
     val i: Int = list.reduce( (x,y) => x-y )
     println("i = " + i)
     // 从源码的角度,reduce 底层调用的其实就是 reduceLeft
     //val i1 = list.reduceLeft((x,y) => x-y)
     // ((4-3)-2-1) = -2
     val i2 = list.reduceRight((x,y) => x-y)
     println(i2)
     }

    Fold 方法

    Fold 折叠:化简的一种特殊情况。

    def main(args: Array[String]): Unit = {
     val list = List(1,2,3,4)
     // fold 方法使用了函数柯里化,存在两个参数列表
     // 第一个参数列表为 : 零值(初始值)
     // 第二个参数列表为: 简化规则
     // fold 底层其实为 foldLeft
     val i = list.foldLeft(1)((x,y)=>x-y)
     val i1 = list.foldRight(10)((x,y)=>x-y)
     println(i)
     println(i1)
     }

    两个集合合并

    def main(args: Array[String]): Unit = {
     // 两个 Map 的数据合并
     val map1 = mutable.Map("a"->1, "b"->2, "c"->3)
     val map2 = mutable.Map("a"->4, "b"->5, "d"->6)
     val map3: mutable.Map[String, Int] = map2.foldLeft(map1) 
    {
     (map, kv) => {
     val k = kv._1
     val v = kv._2
     map(k) = map.getOrElse(k, 0) + v
     map
     }
     }
     println(map3)
     }

    普通 WordCount 案例

     def main(args: Array[String]): Unit = {
        // 单词计数:将集合中出现的相同的单词,进行计数,取计数排名前三的结 果
        val stringList = List("Hello Scala Hbase kafka", "Hello Scala Hbase", "Hello Scala", "Hello")
        // 1) 将每一个字符串转换成一个一个单词
        val wordList: List[String] =
          stringList.flatMap(str=>str.split(" "))
        //println(wordList)
        // 2) 将相同的单词放置在一起
        val wordToWordsMap: Map[String, List[String]] =
        wordList.groupBy(word=>word)
        //println(wordToWordsMap)
        // 3) 对相同的单词进行计数
        // (word, list) => (word, count)
        val wordToCountMap: Map[String, Int] =
        wordToWordsMap.map(tuple=>(tuple._1, tuple._2.size))
        // 4) 对计数完成后的结果进行排序(降序)
        val sortList: List[(String, Int)] =
          wordToCountMap.toList.sortWith {
            (left, right) => {
              left._2 > right._2
            }
          }
        // 5) 对排序后的结果取前 3 名
        val resultList: List[(String, Int)] = sortList.take(3)
        println(resultList)
      }

    复杂 WordCount 案例

    def main(args: Array[String]): Unit = {
        // 第一种方式(不通用)
        val tupleList = List(("Hello Scala Spark World ", 4), ("Hello Scala Spark", 3), ("Hello Scala", 2), ("Hello", 1))
        val stringList: List[String] = tupleList.map(t=>(t._1 + "") * t._2)
        //val words: List[String] =
        stringList.flatMap(s=>s.split(" "))
        val words: List[String] = stringList.flatMap(_.split(" "))
        //在 map 中,如果传进来什么就返回什么,不要用_省略
        val groupMap: Map[String, List[String]] =
          words.groupBy(word=>word)
        //val groupMap: Map[String, List[String]] = words.groupBy(_)
        // (word, list) => (word, count)
        val wordToCount: Map[String, Int] = groupMap.map(t=>(t._1,
          t._2.size))
        val wordCountList: List[(String, Int)] =
          wordToCount.toList.sortWith {
            (left, right) => {
              left._2 > right._2
            }
          }.take(3)
        //tupleList.map(t=>(t._1 + " ") * t._2).flatMap(_.split(" ")).groupBy(word=>word).map(t=>(t._1, t._2.size))
        println(wordCountList)
      }
    def main(args: Array[String]): Unit = {
        val tuples = List(("Hello Scala Spark World", 4), ("Hello Scala Spark", 3), ("Hello Scala", 2), ("Hello", 1))
        // (Hello,4),(Scala,4),(Spark,4),(World,4)
        // (Hello,3),(Scala,3),(Spark,3)
        // (Hello,2),(Scala,2)
        // (Hello,1)
        val wordToCountList: List[(String, Int)] = tuples.flatMap
        {
          t => {
            val strings: Array[String] = t._1.split(" ")
            strings.map(word => (word, t._2))
          }
        }
        // Hello, List((Hello,4), (Hello,3), (Hello,2), (Hello,1))
        // Scala, List((Scala,4), (Scala,3), (Scala,2)
        // Spark, List((Spark,4), (Spark,3)
        // Word, List((Word,4))
        val wordToTupleMap: Map[String, List[(String, Int)]] =
        wordToCountList.groupBy(t=>t._1)
        val stringToInts: Map[String, List[Int]] =
          wordToTupleMap.mapValues {
            datas => datas.map(t => t._2)
          }
        println(stringToInts)
    
     val wordToCountMap: Map[String, List[Int]] =
    wordToTupleMap.map {
     t => {
     (t._1, t._2.map(t1 => t1._2))
     }
     }
     val wordToTotalCountMap: Map[String, Int] =
    wordToCountMap.map(t=>(t._1, t._2.sum))
     println(wordToTotalCountMap)
    
    
      }

    队列

    Scala 也提供了队列(Queue)的数据结构,队列的特点就是先进先出。进队和出队的方 法分别为 enqueue 和 dequeue。

    def main(args: Array[String]): Unit = {
     val que = new mutable.Queue[String]()
     que.enqueue("a", "b", "c")
     println(que.dequeue())
     println(que.dequeue())
     println(que.dequeue())
     }
  • 相关阅读:
    如何轻松的从GAC文件夹拷贝dll出来
    UIManager的用法(用于改变界面风格)
    Java休眠睡眠方法
    Thread.currentThread().getContextClassLoader()与Test.class.getClassLoader()的区别
    Openfire编译命令
    Openfire插件开发
    通过Java代码打开浏览器,本地文件目录以及ftp站点
    使用Pack200压缩你的代码
    Java 创建文件与创建文件夹
    Openfire插件制作
  • 原文地址:https://www.cnblogs.com/wfswf/p/15783969.html
Copyright © 2011-2022 走看看