大数据8_08_Scala集合&常用方法

9 集合

Scala的集合有三大类:序列Seq、集Set、映射Map,所有集合都扩展自Iterable特质。对于所有的集合类,Scala都同时提供了可变和不可变的版本。

可变集合和不可变集合使用包名区分:scala.collection.immutable scala.collection.mutable

可变不可变
数组ArrayArrayBuffer
序列(List)Seq、ListListBuffer
集合Setmutable.Set
映射Mapmutable.Map
元组Tuple\

9.1 数组

①数组的声明

scala中的数组在编译时其实就是编译为java中的数组

scala中数组的声明形式:方式1:只声明不初始化

//方式1:
val array1 : String = new Array[String](3)
//方式2:
val array2 : String = new Array(3)
//方式3:
val array3 = new Array[String](3)

image-20201116231146411

scala中数组的声明形式:方式2:声明的同时初始化

object Test01_Collection_Array_2 {
  def main(args: Array[String]): Unit = {
    //TODO 创建数组的同时进行初始化
    //Java中:String[] array = new String[]{"Tom", "Jerry"};

    //伴生对象(参数) => 伴生对象.apply(参数)
    val array = Array(1, 2, 3, 4)
    val array1 : Array[Int] = Array(10, 12, 13, 14)

    //更新数组中的值
//    array(2) = 6
    array.update(2, 5)

    //将一个数组加在另一个数组上
    val array2 = array.++(array1)   //将array1加在后面

    val array3 = array1 ++: array   //将array1加在前面

    println(array3.mkString(","))
    
  }
}
②数据的访问:
object TestArray {
  def main(args: Array[String]): Unit = {
    //方式1:
    val array1 : Array[String] = new Array[String](3)
    //方式2:
    val array2 : Array[String] = new Array(3)
    //方式3:
    val array3 = new Array[String](3)

    //数据访问
    //scala中中括号用来表示泛型,使用小括号来表示数组索引位置
    array1(0) = "Tom"
    array1(1) = "Jerry"
    
    //数组的遍历
    //方式1:
    for(a <- array1){
      println(a)
    }
    //方式2:
    println(array1.mkString(","))
    //方式3:foreach方法就是为了遍历数据,所以将循环的每一个数据传递到处理函数中
    array1.foreach((s:String) => println(s))
    array1.foreach(println(_))
    array1.foreach(println)
  }
}
③不可变

scala默认的集合都是不可变的,当添加数据时,会生成一个新的集合

不可变数组,1 添加数据到数组的前面:

5 +: array 或者 array.+:(5)

2 添加数据到数组的后面:

array :+ 5

3 添加数组到数组的后面

array ++ array1 或者 array.++(array1)

array1 ++ array 或者 array1.++(array)

object TestArray1 {
  def main(args: Array[String]): Unit = {
    //TODO 数组不可变
    //scala中默认的集合都是不可变的
    val array = new Array[String](3)
    array(0) = "Tom"

    //添加数据
    //scala默认的集合都是不可变的,当添加数据时,会生成一个新的集合
    //scala中如果不采用方法调用,而是采用运算符的方式调用的话
    //如果这个运算符以冒号结尾,那么运算规则为从右向左执行
    //    val array1 = array.+:("Jerry")  //加载数组前面
    val array1 = "Jerry" +: array //加载数组前面

    //    val array1 = array :+ "Jerry" //加载数组后面
    //    val array1 = array +: "Jerry" //将Jerry的每一个元素加载数组后面
    println(array1.mkString(","))   
  }
}

基本操作:

object Test01_Collection_Array_3 {
  def main(args: Array[String]): Unit = {
    val array = Array(1, 2, 3, 4)
    val array1: Array[Int] = Array(4, 5, 6, 7, 8)

    //1 添加数组元素,创建新的数组
    val array2 = array :+ 5

    //2 添加集合
    val array3 = array ++ array1
    val array4 = array ++: array1

    //3 合并数组
    val array6 = Array.concat(array, array1)
//    println(array6.mkString(","))

    //4 创建指定范围的数组
    val array7 = Array.range(0, 2)
    println(array7.mkString(",")) //0,1

    //5 创建并填充指定数量的数组(可以创建多维数组)
    val array8 = Array.fill[Int](5, 2)(-1)
//    println(array8.mkString(","))
    array8.foreach(arr => println(arr.mkString(",")))

    //6 多维数组
    val array5 = Array.ofDim[Int](3, 5)
    array5.foreach(list => println(list.mkString(",")))
  }
}
④ 可变数组ArrayBuffer

默认初始化长度为16

object Test01_Collection_ArrayBuffer {
  def main(args: Array[String]): Unit = {
    //默认情况下,scala提供的集合数组不可变,但是也提供了可变的集合数组ArrayBuffer
    //集合中,创建集合最常见的方法是伴生对象的apply()


    //伴生类的方式创建可变数组
    val buffer = new ArrayBuffer[String]()

    //伴生对象创建可变数组
    val buffer1 = ArrayBuffer(1, 2, 3, 4)
    val buffer2 = ArrayBuffer(5, 6, 7, 8)

    //1 增加数据
    //可变数组,增加数据可以对原来的集合进行改变
    buffer1.append(5)
    buffer1.insert(1, 6)

    //添加集合
    buffer1.appendAll(buffer2)

    //2 修改数据
    buffer1.update(1, 100)

    //3 删除数据
    buffer1.remove(1)
    //删除从索引为1后面的4个数据
    buffer1.remove(1, 4)

    //4 遍历数据
    buffer1.foreach(println(_))
    println(buffer1.mkString(","))

    println(buffer1)


    //5 不可变集合的操作都使用运算符
    //可变集合的操作都使用方法
    buffer1+=4    //加在后面
    44 +=: buffer1  //加在前面
    
    println(buffer1)
  }
}
⑤ 可变和不可变数组的转换
object Test01_Collection_ArrayBuffer_1 {
  def main(args: Array[String]): Unit = {
    //    val array = new Array[Int](4)
    val array = Array(1, 2, 3, 4)
    val buffer = ArrayBuffer(1, 2, 3, 4)

    //可变 => 不可变
    val buffer1: mutable.Buffer[Int] = array.toBuffer
    
    //不可变 => 可变
    val array1: Array[Int] = buffer.toArray
    
  }
}

9.2 序列Seq(List)

①不可变
object Test01_Collection_Seq {
  def main(args: Array[String]): Unit = {
    //TODO 集合-序列Seq(List)
    //List:有序的,数据可重复的
    val seq = Seq(1, 2, 3, 4)

    //在使用序列的集合时,使用的最多的为List

    //构建不可变的序列集合
    val list = List(1, 2, 3, 4)

    //5 是加在集合的后面
    val list1 = list :+ 5

    //6 是加在集合的前面
    val list2 = 6 +: list

    println(list)
    println(list2)

    //创建List空集合
    //空集合
    val nil = Nil
    //    println(nil)

    //向空集合中添加数据
    println(1::2::3::4::Nil)
    val list3 = List(9, 9, 9, 9)

    //将一个list集合作为整体添加到空集合中
    println(1::2::3::4::list3::Nil)   //List(1, 2, 3, 4, List(9, 9, 9, 9))

    //将整体拆分成一个一个的个体来使用,称为扁平化
    println(1::2::3::4::list3:::Nil)  //List(1, 2, 3, 4, 9, 9, 9, 9)

  }
}
②可变的序列ListBuffer
object Test01_Collection_Seq_1 {
  def main(args: Array[String]): Unit = {
    val buffer = ListBuffer(1, 2, 3, 4)
    buffer.append(5)
    buffer.appendAll(List(1,1,1))
    buffer.insert(1, 6)

    buffer.update(1, 6)

    buffer.remove(2)
    buffer.remove(1, 3)

    buffer.foreach(println)
    println(buffer.mkString(","))
  }
}

9.3 集合Set

①可变集合Set
object Test01_Collection_Set_1 {
  def main(args: Array[String]): Unit = {

    //TODO 不可变集合Set
    val set = Set(1, 2, 3, 4, 5, 6, 7)
    //1 添加元素
    //不可变集合Set不支持添加修改,可以删除和添加,但是是生成新的Set
    val set1 = set + 10
    val set2 = set.+(11, 12)
    println(set)
    println(set1)
    println(set2)

    //2 删除元素
    val set3 = set - 10
    println(set3)

    //3 遍历集合Set
    set.foreach(println)
    println(set.mkString(","))    
  }
}
②不可变集合Set

Set本身是无序的,不可变的;如果使用mutable.Set,这样的Set集合就是可变的了。但是还是不能重复,且无序。

object Test01_Collection_Set_2 {
  def main(args: Array[String]): Unit = {
    //TODO 可变集合mutable.Set

    val set = mutable.Set(1, 2, 3, 4, 5, 6, 7)

    //1 添加数据,可变集合mutable.Set是在原集合的基础上添加数据
    set.add(10)
    //update(11, true),表示在set中添加11这个元素,
    //update(1, false),表示从set中排除1这个元素
    set.update(11, true)

    //2 删除数据
    //set.remove(1) 等同于 update(1, false)
    set.remove(1)

    //3 遍历集合
    set.foreach((x:Int)=>{println(x)})
    set.foreach(println(_))
    set.foreach(println)

    //4 生成字符串
    println(set.mkString(","))

    val set1 = mutable.Set(1, 2, 3, 4, 5)
    val set2 = mutable.Set(3, 4, 5, 6, 7, 8)
    //5 交集
    val set3 = set1 & set2
    //6 差集
    val set4 = set1 &~ set2
    println(set)
  }
}

9.4 映射Map

Map存储的是k-v,声明形式有:Map(“a”->1, “b”->2, “c”->3)和:Map((“a”, 1), (“b”, 2), (“c”, 3))

Map的key不能重复,并且key是无序的。但是value可以重复。

①不可变Map
object Test01_Collection_map_1 {
  def main(args: Array[String]): Unit = {
    //TODO 集合-映射转换(Map)
    // TODO 不可变集合Map

    //Map初始化方式1:
    val map = Map("a" -> 1, "b" -> 2, "c" -> 3)
    //Map初始化方式2:以元组的方式
    val map1 = Map(("aa", 11), ("bb", 22), ("cc", 33))

    //1 添加数据,因为map是不可变的,所以生成新的Map
    val map3 = map + ("ee" -> 10)
    val map2 = map1 + (("ee", 10))
    println(map2)
    println(map3)

    //2 修改数据,Map不可变,所以是生成新的Map
    val map4 = map.updated("a", 100)
    println(map)
    println(map4)

    //3 删除数据,Map不可变,生成新的Map
    val map5 = map - "a"
    println(map5)

    //4 遍历Map
    map.foreach(println)

    //5 创建空Map
    val empty = Map.empty
    println(empty)

    //6 获取Map的指定key的value值
    println(map("a"))

    //7 获取可能的key值
    val maybeInt: Option[Int] = map.get("b")
    //判断key值是否存在;不存在None;存在Some(value值)
    println(maybeInt)

    //8 获取可能存在的值,如果不存在就使用默认的值
    println(map.getOrElse("aaa", 11))   
  }
}
②可变Map
import scala.collection.mutable
object Test01_Collection_map_2 {
  def main(args: Array[String]): Unit = {
    //TODO 集合-映射转换(Map)
    // TODO 可变Map

    val map = mutable.Map(("a", 1), ("b", 2), ("c", 3))

    //1 增加数据,mutable.Map是可变的Map,所以原Map会被修改
    map.put("d", 4)

    //2 查询数据
    val maybeInt: Option[Int] = map.get("c")
    //选项类型Option,为了避免出现null值,取到值:Some(value值);没取到值:None

    if (maybeInt.isEmpty){
      println("要查找的数据不存在")
    }else{
      println(maybeInt.get)
    }

    //3 修改数据
    map.update("a", 11)

    //4 删除数据
    map.remove("a")

    //5 Map转List
    val list = map.toList
    println(list)

    //6 遍历Map,转成String
    println(map.mkString(","))
    //遍历values
    println(map.values.mkString(","))
    //遍历keys
    println(map.keys.mkString(","))

    //7 Map的迭代器
    val iterator = map.iterator
    while (iterator.hasNext){
      println(iterator.next())
    }
    //Map的key的迭代器
    val iterator1 = map.keysIterator
    val iterator2 = map.keys.iterator
    //Map的value的迭代器
    val iterator3 = map.valuesIterator
    val iterator4 = map.values.iterator

    //8 Map的foreach
    map.foreach(println)
    
    //9 清除Map
    map.clear()

    println(map)
  }
}

9.5 元组 Tuple

object Test01_Collection_tuple {
  def main(args: Array[String]): Unit = {
   //TODO 元组
    //scala中将无关的数据作为一个整体来使用,形成了一个元素的数据组合,简称为元组(Tuple)
    //scala中元组使用小括号声明

    //元组的类型
    //元组的类型最多只能容纳22个
    //只是限制了数据容纳的个数,没有限制数据容纳的类型
    val tuple: (Int, String, Char, Double) = (1, "Tom", 'a', 22.2)
    //元组数据的访问
    //根据有效的序号访问
    println(tuple._1)
    println(tuple._2)
    println(tuple._3)
    println(tuple._4)

    //1 采用数据在元组中的索引访问
    println(tuple.productElement(1))
    //2 采用迭代器的方式访问
    val iterator = tuple.productIterator
    while (iterator.hasNext){
      println(iterator.next())
    }
  }
}
  • 元组中只有2个元素,那么这样的元素称为对偶元组,也成为键值对
object Scala06_Collection_Tuple_1 {

    def main(args: Array[String]): Unit = {

        // TODO 集合 - 元组
        // 如果元组中只有2个元素,那么这样的元组称之为对偶元组,也称之为键值对
        //val kv = ("a", 1)

        // map集合中的键值对其实就是元组
        //val tuple: ((String, String), Int) = "a" -> "b" -> 1
        val map = Map( ("a", 1), ("b", 2), ("c", 3) )

        for ( kv <- map ) {
            println(kv._1 + "," + kv. _2)
        }
    }
}
  • 元组中的每一个元素不能更改
object Scala06_Collection_Tuple_2 {

    def main(args: Array[String]): Unit = {
        // TODO 集合 - 元组
        // 元组中的每一个元素不能被更改
        val t = (1, "zhangsan", 30)
        //t._1 = 2
    }
}

9.6 队列

import scala.collection.mutable

object Scala07_Collection_Queue {

    def main(args: Array[String]): Unit = {

        // TODO 集合 - 队列
        val que = new mutable.Queue[String]()
        // 添加元素
        que.enqueue("a", "b", "c")
        val que1: mutable.Queue[String] = que += "d"
        println(que eq que1)
        // 获取元素
        println(que.dequeue())
        println(que.dequeue())
        println(que.dequeue())
    }

}
①kafka中如何保证消费数据的有序?
  • 1 分区间无序,分区内有序(保存数据有序)
  • 2 生产者端采用双端队列(生产数据有序)

image-20201117011611463

9.7 并行

import scala.collection.mutable

object Scala08_Collection_Par {

    def main(args: Array[String]): Unit = {

        // TODO 集合 - 并行
        val result1 = (0 to 100).map{x => Thread.currentThread.getName}
        val result2 = (0 to 100).par.map{x => Thread.currentThread.getName}

        println(result1)
        println(result2)
    }

}
①串行 & 并行 & 并发

image-20201117011803193

image-20201117011818983

image-20201117011842551

10 常用方法

10.1 常用方法

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

        // 1 集合长度
        println("size =>" + list.size)
        println("length =>" + list.length)
        // 2 判断集合是否为空
        println("isEmpty =>" + list.isEmpty)
        // 3 集合迭代器
        println("iterator =>" + list.iterator)
        // 4 循环遍历集合
        list.foreach(println)
        // 5 将集合转换为字符串
        println("mkString =>" + list.mkString(","))
        // 6 判断集合中是否包含某个元素
        println("contains =>" + list.contains(2))
        // 7 取集合的前几个元素
        println("take =>" + list.take(2))
        // 8 取集合的后几个元素
        println("takeRight =>" + list.takeRight(2))
        // 9 查找元素
        println("find =>" + list.find(x => x % 2== 0))
        // 10 丢弃前几个元素
        //mutable.List 丢弃后几个为什么不会改变原数组???
        //这是因为drop和去重都是产生新的数组,如果想删除原数组元素,可以使用remove
        println("drop =>" + list.drop(2))
        // 11丢弃后几个元素
        println("dropRight =>" + list.dropRight(2))
        // 12 反转集合
        println("reverse =>" + list.reverse)
        // 13 去重
        println("distinct =>" + list.distinct)
    }
}

10.2 衍生集合

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

        // 1 集合头
        println("head => " + list.head)
        // 2 集合尾
        println("tail => " + list.tail)
        // 3 集合尾迭代
        println("tails => " + list.tails)
        // 4 集合初始值
        println("init => " + list.init)
        // 5 集合初始值迭代
        println("inits => " + list.inits)
        // 6 集合最后元素
        println("last => " + list.last)
        // 7 集合并集
        println("union => " + list.union(list1))
        // 8 集合交集
        println("intersect => " + list.intersect(list1))
        // 9 集合差集
        println("diff => " + list.diff(list1))
        // 10 切分集合
    	//切分集合怎么切分的??
    	//splitAt(n),切成两个,第一个集合的数量就是n,第二个几个的数量是剩下的
        println("splitAt => " + list.splitAt(2))
        // 滑动(窗口)
        println("sliding => " + list.sliding(2))
        // 滚动(没有重复)
        println("sliding => " + list.sliding(2,2))
        // 拉链
   		//如果一个List的数量多另一个List的数量少,另一个就没有了
        println("zip => " + list.zip(list1))
        // 数据索引拉链,结果是(数据,索引)
        println("zipWithIndex => " + list.zipWithIndex)
    }
}

10.3 计算函数

object Function3 {
  def main(args: Array[String]): Unit = {
    //TODO 计算函数

    val list = List(1, 2, 3, 4)
    val list1 = List(6, 7, 8, 9)
    val set = mutable.Set(2, 3, 5, 3)
    val map = mutable.Map(("a", 1),("a", 1),("d", 11), ("b", 2), ("c", 3))


    // 1 集合的最小值
    println(list.min)
    println(set.min)
    println(map.min)//TODO map的最小值和最大值,好像是根据key的大小??
    //2 集合的最大值
    println(list.max)
    println(set.max)
    println(map.max)
    //3 集合求和
    println(list.sum)
    println(set.sum)
    //TODO map的sum函数怎么用???

    //4 集合乘积
    println(list.product)
    println(set.product)
	//TODO map的product函数怎么用???
      
    //5 集合简化规约reduce
    println(list.reduce((x: Int, y: Int) => {
      x - y
    }))
    println(set.reduce(_ + _))
    //6 集合简化规约(左) 就等同于reduce (((1 - 2) - 3) - 4) = -8
    println(list.reduceLeft(_ - _))
    //7 集合简化规约(右) (1 - (2 - (3 - 4))) = -2
    println(list.reduceRight(_ - _))
    //8 集合折叠(函数柯里化)
    //fold方法存在两个参数列表
    //第一个参数列表中的参数表示计算的初始值
    //第二个参数列表中的参数表示以第一个参数为基准,两两计算的逻辑
    println(list.fold(6)(_ - _))
    //9 就等同于fold()()
    println(list.foldLeft(6)(_ - _))  //((((6 - 1) - 2) - 3) - 4)  = -4
    //10 从右边折叠
    println(list.foldRight(6)(_ - _))  // (1 - (2 - (3 - (4 - 6)))) = 4
    //11 集合扫描
    //scan方法会保留所有的计算过程的数据
    println(list.scan(6)(_ - _))
    //12 scanLeft
    println(list.scanLeft(6)(_ - _))
    //13 scanRight
    println(list.scanRight(6)(_ - _))
  }
}

10.4 功能函数

object Function4 {
  def main(args: Array[String]): Unit = {
    //TODO 功能函数
    val list = List(1, 2, 3, 4, 5)
    val map = mutable.Map(("a", 1), ("b", 2), ("c", 3))

    //1 集合映射map
    list.map((x: Int) => println(x * 2))
    println(list.map(_ * 2))

    //2 集合扁平化flatten
    //将集合整体拆分成一个个的个体来使用。
    val buffer = ListBuffer(List(1, 2, 3, 4), List(4, 8, 7, 6))
    println(buffer.flatten)

    val set = mutable.Set(List(1, 2, 3, 4), List(3, 4, 9, 8))
    println(set.flatten)

    //flatten只能拆除外层包装:
    val list1 = List(List(List(1, 2, 3)), List(List(1, 1)))
    println(list1.flatten)  //List(List(1, 2, 3), List(1, 1))
    println(list1.flatten.flatten)  //List(1, 2, 3, 1, 1)

    //3 自定义扁平化flatMap
    val list2 = List("hello world scala", "hello spark")
    val words = list2.flatMap(s => {
      val word = s.split(" ")
      word
    })
    println(words.mkString(","))

    //4 集合过滤数据filter
    println(list.filter((x: Int) => {
      x % 2 == 0
    }))
    println(list.filter(_ % 2 == 0))

    //5 集合分组数据groupBy
    //分组后,返回的结果是Map类型,key是分组的K,value是符合分组K的数据集合
    val list3 = List("hello","world","scala","hello","spark")
    val groupMap = list3.groupBy((s: String) => {
      s.substring(0, 1)
    })
    println(groupMap) //Map(w -> List(world), h -> List(hello, hello), s -> List(scala, spark))


    //6 集合排序sortBy
    //对上面的结果,统计w和h和s开头的单词的个数,然后排序
    val sumList = groupMap.toList.map(t => {
      val size = t._2.size
      (t._1, size)
    })
    println(sumList)

    //排序默认是升序排序
    //更改为降序排序使用.Ordering.Int.reverse
    println(sumList.sortBy(t => t._2))
    println(sumList.sortBy(t => t._2)(Ordering.Int.reverse))
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最佳第六六六人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值