大数据之scala_scala之集合

集合

scala中的集合分为两种 ,可变集合和不可变集合, 不可变集合可以安全的并发的访问!
集合的类主要在一下两个包中
1)可变集合包 scala.collection.mutable
2) 不可变集合包 scala.collection.immutable
scala默认使用的是不可变的集合 , 因此使用可变的集合需要导入可变集合的包
scala的集合主要分成三大类
(1)Seq 序列
(2)Set 不重复集
(3)Map 键值映射集
注意: 所有的集合都继承自Iterator迭代器这个特质
在这里插入图片描述
序列
许多数据结构是序列型的,也就是说,元素可以按特定的顺序访问,如:元素的插入顺
序或其他特定顺序。collection.Seq是一个trait,是所有可变或不可变序列类型的抽象,其子trait collection.mutable.Seq及collection.immutable.Seq分别对应可变和不可变序列。
从上面的图中可以看出Array,String ,List都属于序列

不可变数组

数组的基本操作 , scala中的数组和java中的不太一样 ,这里的数组类似于一个数组对象 .有自己的方法!!

数组的定义

def main(args: Array[String]): Unit = {
  // 定义一个通用数组 没有执行数据类型 , 可以存储任意类型
  val arr1 = Array("JIM", 12, 12.22, true)
  // 指定泛型 约束数组中的数据类型  只能写泛型的子类
  val arr2 = Array[Any]("JIM", 12, 12.22, true)
  // 定义数组 定义数据类型   只能存储Int类型
  val arr3 = Array[Int](1, 2, 3, 4)

数组的基本操作

 // 数组的取值
  println(arr3(0))
  //数组元素重新赋值
   arr3(0) = 100
  // 数组的遍历 方式一
  for(e <- arr3){
    println(e)
  }
  // 方式二
  for (i <- 0 until arr3.length){
    println(arr3(i))
  }
  // 方式三 仅仅用于打印
  arr3.foreach(e=>print(e+" "))
  arr3.foreach(println(_))
 // 方式四 map方法会取出来每个元素进行操作 
  arr3.map(x=> println(x))
  arr3.map(println(_))
}

数组中的方法

 val arr = Array(1,3,5,7,9,2,6,4)
 // 数组中的最大和最小值
 val min: Int = arr.min
 val max: Int = arr.max
 // 首个元素
 val head: Int = arr.head
 //最后一个元素
 val last: Int = arr.last
 // 去除首个元素的子数组
 val arr11: Array[Int] = arr.tail
 // 将数组转换成List集合
 val list: List[Int] = arr.toList
 // 获取和后面数组中不同的元素
val diff: Array[Int] = arr.diff(Array(1,111,222))
 //求数组元素的和
 val sum: Int = arr.sum
 // 默认排序
 val sorted: Array[Int] = arr.sorted
 // 数组的长度
 arr.length
 //修改指定位置的元素
 arr.update(1,100)
// 取出数组中的前n个元素
 val arr3: Array[Int] = arr.take(3)
 //  后面添加一个元素  生成 新的数组
 val arr2: Array[Int] = arr.:+(11)
 //  后面添加一个数组
 val  res = arr:++arr3
// 统计符合条件的个数
 val i: Int = arr.count(_>2)
 // 数组反转
 arr.reverse
// 将不可变数组转换成可变数组
val buffer: mutable.Buffer[Int] = arr.toBuffer

可变数组

导入可变数组 : import scala.collection.mutable.ArrayBuffer ,可以修改元素的数组为可变数组

private val arr = ArrayBuffer(12,23,34,45,56,67)
val  arr1 = Array(101, 102)
// 数组中添加一个元素
arr += 78
// 数组中合并一个数组的数据
arr++=arr1
// 除去数组中的一个元素
arr-=78
// 移出一个数组的元素
arr--=arr1
//移出角标位置为2 的数据
 arr.remove(2)
// 从0位置删除2个元素  参数一 坐标  参数2  删除元素的个数
arr.remove(0,2)
//将可变数组转换成不可变数组
arr.toArray

List

不可变List

// 不可变的List集合 数据不允许被修改
  private val ls1 = List("SCALA", "HDP", "SPARK" , 12 , 34)
  // 向Nil空队列中添加元素组成新的队列
  val ls2 = "HIVE" :: "MYSQL" :: "HBASE" :: Nil
  // Nil 和 List.empty[Nothing]是等价的
  private val ll = List.empty[Nothing]
  ls1(0) // 获取指定位置元素
  // 添加一个元素生成新的List
  val ls3 = ls1 :+ "PYTHON"
  //合并两个集合 生成新的集合
  val ls4 = ls1 ++ ls2
  ls1.foreach(println)
  // 获取前两个元素 组成新的List
  ls1.take(2)
  println(ls1.take(2))
  println(ls1.takeRight(2))  // 从右边取数据
// 遍历每个元素   参数是一个偏函数
 ls1.collect({ case x: Int => x })
  // 查找匹配的元素 仅仅返回一个元素 
 ls1.find(x=>x.toString.startsWith("S"))
// 判断是否为null集合
 ls1.isEmpty
// 转换成可变List集合
ls1.toBuffer

可变List

val ls1 = ListBuffer(1, 3, 5, 7)
val ls2 = ListBuffer(2, 4, 6, 8)
ls1 += 9
ls1 -= 9
//并入一个list
ls1 ++= ls2
ls1 --= ls2
//  ls1.clear()
ls1.size
ls1.length
// 转换成不可变集合 
ls1.toList
// ls1.update(1,100)
ls1.head
ls1.tail
// 合并两个集合
val ls3 = ls1 ++ ls2
println(ls3)

Set

Set和list的最大区别在于Set中不可以存储重复数据 ,通常使用Set来实现元素的去重!!
Set集合也分为可变Set和不可变的Set,使用包名来区分可变和不可变

/ 不可变集合
val s = Set(1, 2, 3, 4, 4, 5)
s.exists(x=>x>1)
// 可变se
import scala.collection._
val set = new mutable.HashSet[Int]()
set.add(12)
set += 21
set.remove(12)
set.foreach(println)

特殊的集合元组

scala中存在一种特殊的集合元组, 元组中可以存储任意类型的元素 ,但是只能存储22个 , 其中对偶元组经常用作键值映射
与列表一样,元组也是不可变的,但与列表不同的是元组可以包含不同类型的元素。
注意productIterator的用法

// 创建一个三个元素的元组
val tp = new Tuple3(1,3,4)

val tuple: (Int, Double, String) = (1, 3.14, "Fred")
// 获取指定位置的元素
tuple._2
// 迭代元组
tuple.productIterator.foreach(println)
// 元组转换成字符串
val str: String = tuple.toString()
println(str)
// 对偶元组
val tuple2: ((String, String), (String, String), (String, String), (String, String)) = (("wd", "zsf"), ("sl", "fsy"), ("em", "shit"), ("huashan", "lhc"))
// 获取对偶元组第一个元素的key的值
println(tuple2._1._1)
val tp = (String, String)
// 交换位置
tp.swap

Map映射

Map集合也是分为可变Map和不可变Map , 使用包名来区分是可变M安排还是不可变Map

// 不可变的Map
 val map1 = Map[String, Int](
   ("n1", 10),
   ("n2", 11),
   ("n3", 12)
 )
 val map2 = Map[String, Int](
   "n1" -> 10,
   "n2" -> 11,
   "n3" -> 12
 )
 val m: HashMap[String, Int] = HashMap[String, Int]("n3" -> 12)
 //不可变的map没有put方法
 // 定义可变的集合
 import scala.collection._
 val map = new mutable.HashMap[String, String]()
 map.put("wd", "ssf")
 map.put("sl", "fsy")
 // 根据key获取元素 , 没有给默认值
 map.getOrElse("", "")
 // 根据key更新数据  没有不做操作
 val str: String = map.getOrElseUpdate("s2", "haha")
 // 删除key
 map.remove("")
 map.get("")
 map.+=(("",""))
 map.update("","")
 val arr: Array[(String, String)] = map.toArray
 //是否包含
 map.contains("")
 // 返回迭代器
 map.keys
 //返回set
 map.keySet
map.take(1)

Map的遍历
map的遍历方式多种多样

val map = Map[String, Int](
  ("n1", 10),
  ("n2", 11),
  ("n3", 12)
)
// 循环获取键值对
for (e <- map) {
  val key = e._1
  val value = e._2
}
// 元组的形式接受键值对
for ((k, v) <- map) {
  println(k)
  println(v)
}
// 只接受key
for ((k, _) <- map) {
  println(k)
}
// 只接受value
for ((_, v) <- map) {
  println(v)
}
//返回所有的key
val keys: Iterable[String] = map.keys
val set: Set[String] = map.keySet
for (key <- keys) {
// 根据key获取value
  val value: Option[Int] = map.get(key)
  val v = value.get
}
for (key <- set) {
  val value: Option[Int] = map.get(key)
  val v = value.get
}
// 获取所有的values
val values: Iterable[Int] = map.values
// map转换成对偶元组的List和Array
val list: List[(String, Int)] = map.toList
val array: Array[(String, Int)] = map.toArray

Option

Option(选项)类型用来表示一个值是可选的(有值或无值)。
Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 。
Option 有两个子类别,一个是 Some,一个是 None,当他回传 Some 的时候,代表这个函式成功地给了你一个 String,而你可以透过 get() 这个函式拿到那个 String,如果他返回的是 None,则代表没有字符串可以给你。

al myMap: Map[String, String] = Map("key1" -> "value")
val value1: Option[String] = myMap.get("key1")
val value2: Option[String] = myMap.get("key2")
println(value1) // Some("value1")
println(value2) // None

集合中的常用方法

forEach

迭代遍历集合中的每个元素,对每个元素进行处理 ,但是没有返回值 ,常用于打印结果数据 !

val ls = List(1,3,5,7,9)
ls.foreach(println) // 打印每个元素
ls.foreach(println(_))// 打印每个元素
ls.foreach(x=>println(x*10)) // 每个元素乘以10 打印结果
ls.foreach(x=>print(x+" "))// 打印每个元素 空格隔开

map

适用于任意集合
注意Map集合的用法
map函数遍历每个元素处理返回原集合类型的新集合 , 也可以不返回数据
列表,数组,Map中都有map函数 元组中没有map函数

val arr = Array[String]("JAVA", "C++", "SCALA")
val ls = List(1, 3, 5, 7, 9)
val set = Set(1, 3, 5, 7)
val mp = Map[String, Int]("ZSS" -> 100, "LSS" -> 99)
// map函数遍历每个元素处理返回原集合类型的新集合
val new_arr: Array[String] = arr.map(x => x)
val new_list: List[Int] = ls.map(x => x)
val new_set: Set[Int] = set.map(x => x)
// Map集合使用map函数
val new_Map1: Map[String, Int] = mp.map({ case v: (String, Int) => (v._1, v._2 * 10) })
val new_Map2: Map[String, Int] = mp.map(e => (e._1, e._2 + 100))

// map函数也可以不返回数据
ls.map(println(_))

filter和filterNot

适用于 数组 List Map
filter返回符合自己条件的新的集合,filterNot返回不符合自己条件的新的集合

val ls: List[Int] = List.range(1,10)
ls.filter(x=>x%2==0)
val new_list: List[Int] = ls.filter(_ % 2 == 0)//  _ 代表每个元素
new_list .foreach(x=>print(x+"  "))  // 2  4  6  8
ls.filterNot(_%2!=1).foreach(x=>print(x+"  ")) 1  3  5  7  9  
每个元素进行过滤
val set = Set("spark" , "scala" , "c++" , "java")
val new_set: Set[String] = set.filter(_.startsWith("s"))
set.filter(_.length>3)
多条件filter进行条件过滤
val ls = "spark":: "scala" :: "c++"::"java"::1::2::12.34::Nil
// 过滤出选过滤出String类型的和Double类型的数据
ls.filter{
  case i:String => true
  case i:Int=>false
  case i:Double=>true
} 

连续使用多次filter进行条件过滤

// 连续使用多次filter进行条件过滤
val map = Map[String,Int](("zss" ,91),("zww",89),("zzx",92) , ("ww",23))
map.filter(_._1.startsWith("z")).filter(_._2>90)

collect

常于 数组 List Map
collect函数也可以遍历集合中的每个元素处理返回新的集合

def map[B](f: (A) ⇒ B): List[B]
def collect[B](pf: PartialFunction[A, B]): List[B]
主要支持偏函数
val ls = List(1,2,3,4,"hello")
// 主要支持偏函数
 val new_list: List[Int] = ls.collect({case i:Int=>i*10})
 new_list.foreach(x=>print(x+" "))//10 20 30 40
// collect实现filter和map特性
list.collect({ case i: Int => i * 10
case i: String => i.toUpperCase
}).foreach(println)

 val new_list2: List[Int] = ls.map({case x:Int=>x*10})
 new_list2.foreach(x=>print(x+" "))// 错误 hello (of class java.lang.String)

因为collect支持偏函数 , 所以我们可以使用collect实现filter和map的特性!!!

val res: List[Int] = List(1, 2, 3, 4, 5, 6,"hello").collect({case i:Int if i%2==0=>i*10})
res.foreach(println)  // 40  60 是不是牛逼闪电??

min和max

适用于 数组 List Map
数组

val arr = Array(1,2,345,67,5)
arr.min
arr.max
arr.sum
List
val ls = List(1,2,345,67,5)
ls.min
ls.max
ls.sum
Set
val set = Set(1,2,345,67,5)
set.min
set.max
set.sum

map 默认按照key排序获取最大和最小数据

val map = Map[String,Int]("a"->10, "b"->99 , "c"->88)
// map默认按照key排序获取最大和最小数据
map.min  //(a,10)
map.max //(c,88)

minBy和maxBy

适用于 数组 List Map
集合中的min和max可以获取任意集合中的最小和最大值 ,但是如果集合中存储的是用户自定义的类 , 或者是按照Map集合中的key,value规则排序的话就需要用户指定排序规则
map按照value取最大最小

val map = Map[String,Int]("a"->10, "b"->99 , "c"->88)
// map默认按照key排序获取最大和最小数据
// 指定map排序  按照value排序 
map.maxBy(x=>x._2) //(b,99)
map.minBy(x=>x._2) //(a,10)

集合中存储的是用户自定义的类型

class User(val name:String ,val age:Int) {}

方式一 隐式转换

implicit  def ordersUser(user:User)={
  new Ordered[User] {
    override def compare(that: User) = {
       user.age.compareTo(that.age)
    }
  }
}
val ls = List(new User("zs",22),new User("ww",18) ,new User("tq",34))
println(ls.max.name)
println(ls.min.name)

方式二:

println(ls.maxBy(x => x.age).name)
sum

适用于 数组 List Set
求集合中的所有元素的和 ,下面三种集合类型常用

val arr = Array(1,2,345,67,5)
arr.sum

val ls = List(1,2,345,67,5)
ls.sum

val set = Set(1,2,345,67,5)
set.sum

count

适用于 数组 List Map

def count(p: ((A, B)) => Boolean): Int
计算满足指定条件的集合元素数量
val arr = Array(1,2,345,67,5)
arr.count(_>5)  // array list  set 统用

val ls = List("hello" , "hi" , "heihei" , "tom")
ls.count(_.startsWith("h"))
ls.count(_.equals("hello"))
ls.count(_ == "hello")
// 忽略大小写
ls.count(_.equalsIgnoreCase("HELLO"))
// 统计符合条件的map元素的数量 
val map = Map[String,Int]("a"->10,"ab"->10, "b"->99 , "c"->88)
map.count(x=>x._1.startsWith("a"))
map.count(_._2>10)

find

适用于 数组 List Map
查找符合要求的元素 , 匹配到就反回数据 ,最多只返回一个
Option中的数据要么是Some(T) 要么是None标识没有找到

val arr = Array(1,2,345,67,5)
val e: Option[Int] = arr.find(x=>x>1)

val ls = List("hello" , "hi" , "heihei" , "tom")
val res: Option[String] = ls.find(_.contains("a"))
if(res.isDefined){
  println(res)  //Some(hello)
  println(res.get)  //hello

}
val map = Map[String,Int]("a"->10,"ab"->10, "b"->99 , "c"->88)
val res_map: Option[(String, Int)] = map.find(x=>x._2>20)
if(res_map.isEmpty){
  "没有匹配到内容"
}else{
  // 打印数据
  println(res_map.get)
}

flatten

适用于 数组 List
压平 将一个集合展开 组成一个新的集合

val arr = Array(1,2,345,67,5.23)
//val res1: Array[Nothing] = arr.flatten  I数值了类型的无法压平
val ls = List("hello" , "hi" , "heihei" , "tom")
val res2: Seq[Char] = ls.flatten  // 压成单个字符  因为字符串属于序列集合的一种
val map = Map[String,Int]("a"->10,"ab"->10, "b"->99 , "c"->88)
// map无法直接压平
//val flatten: immutable.Iterable[Nothing] = map.flatten
// 压平存储Map集合的list   获取Map中每个元素 
val ls1 = List[Map[String,Int]](Map[String,Int]("a"->10,"ab"->10) , Map[String,Int]("jim"->100,"cat"->99))
ls1.flatten   // List((a,10), (ab,10), (jim,100), (cat,99))

val res: List[Int] = List(Array(1,2,3),Array(4,5,6)).flatten
// 错误  注意压平的数据的类型
 val res4 = List(Array(1,2,3),Array("hel",5,6)).flatten 

flatMap

适用于 数组 List
map+flatten方法的组合 ,先遍历集合中的每个元素 , 再按照指定的规则压平, 返回压平后的新的集合

val ls = List("today is my first day of my life" , "so I feel so happy")
// map处理每个元素 就是处理每句话
 ls.map(x=>println(x))
// 获取集合中的每个元素   获取两句话   然后再扁平成字符
ls.flatMap(x=>x)
// 指定扁平化的规则 按照空格压平  压平的规则
ls.flatMap(x=>x.split(" ")).foreach(println) // 获取到每个单词

map和flatMap处理数据详解

// 读取外部文件
val bs: BufferedSource = Source.fromFile("d://word.txt")
// 读取所有的数据行
val lines: Iterator[String] = bs.getLines()
// m遍历每行数据按照 \\s+ 切割返回一个新的迭代器
val words: Iterator[String] = lines.flatMap(_.split("\\s+"))
// 遍历迭代器 获取每个单词
words.foreach(println)

// 读取外部文件
val bs2: BufferedSource = Source.fromFile("d://word.txt")
  // 获取所有的行数据 
val lines2: Iterator[String] = bs2.getLines()
// 处理每行数据 切割单词后  每行返回一个数组   将所有的数组封装在迭代器中
val arrs: Iterator[Array[String]] = lines2.map(_.split("\\s+"))

mapValues

适用于 Map
mapValues方法只对Map集合的value做处理!
新版本的scala中已经废弃了这个方法 可以单独使用 map.values来单独处理map中所有的value数据!

sorted

适用于 数组 List Map
sorted 使用域简单的数字, 字符串等排序规则简答的集合进行排序 , 如果需要定制化排序建议使用sortBy 和 sortWith函数
List对数值

val  list = List (1, 34 , 32 , 12 , 20 ,44 ,27)
// 返回排好序的list集合   默认从小到达排序
val sorted: List[Int] = list.sorted
对Array字符串
val arr = Array("jim" , "cat" , "jong" , "huba")
// 字符串默认按照先后排序
val sorted_arr: Array[String] = arr.sorted
对Map
val map = Map[String , Int]("aeiqi"->4 , "qiaozhi"->2 , "baji"->34)
// map集合也没有sorted 函数 只有转换成List或者Array集合 默认按照key字典先后排序
val sorted_map: Seq[(String, Int)] = map.toList.sorted
sorted_map.foreach(println)


implicit  def ordersUser(user:User)={
  new Ordered[User] {
    override def compare(that: User) = {
      that.age.compareTo(user.age)
    }
  }
}
val u1 = new User("wuji",34)
val u2 = new User("zhiruo",24)
val u3 = new User("zhoamin",44)
val u4 = new User("cuishan",64)
// Set集合中没有sorted方法  如果指定规则排序 转成成List集合
val set  = Set(u1, u2 , u3 , u4)
// 默认按照用户指定的排序规则排序
val sorted_set = set.toList.sorted
sorted_set.foreach(println)

sortBy和sortWith

适用于 数组 List Map

var arr = Array(1, 11, 23, 45, 8, 56)
val arr1 = arr.sortBy(x => x) //ArraySeq(1, 8, 11, 23, 45, 56)
//按照数据倒序排列
val arr2 = arr.sortBy(x => -x) //(56, 45, 23, 11, 8, 1)
// 按照字典顺序排序
val arr3 = arr.sortBy(x => x.toString) //ArraySeq(1, 11, 23, 45, 56, 8)
// x 前面的元素  y 后面的元素
arr.sortWith((x, y) => x > y)
arr.sortWith((x, y) => x < y)

var list = List("hello", "cat", "happy", "feel")
// 字典顺序
list.sortBy(x => x)
// 执行排序
list.sortWith((x, y) => x > y)
list.sortWith((x, y) => x < y)

val map = Map("peiqi" -> 5, "jong" -> 3, "baji" -> 12)
map.toList.sortBy(x => x._1) //List((baji,12), (jong,3), (peiqi,5))
map.toList.sortBy(x => x._2) //List((jong,3), (peiqi,5), (baji,12))
// 指定key排序
map.toArray.sortWith((x,y)=>x._1>y._1)
map.toArray.sortWith((x,y)=>x._1<y._1)
//指定value排序规则
map.toArray.sortWith((x,y)=>x._2>y._2)
map.toArray.sortWith((x,y)=>x._2<y._2)

自定义类型在集合中的排序

val u1 = new User("wuji", 34)
val u2 = new User("zhiruo", 24)
val u3 = new User("zhoamin", 44)
val u4 = new User("cuishan", 64)

var arr = Array(u1, u2, u3, u4)
// 按照姓名字典排序
arr.sortBy(user => user.name)
//年龄小到大
arr.sortBy(user => user.age)
//数值类型的排序可以直接使用- 来倒序排列 年龄大到小
arr.sortBy(user => -user.age)
// 年龄大到小
arr.sortWith((user1, user2) => user1.age > user2.age)
// 年龄小到大
arr.sortWith((user1, user2) => user1.age < user2.age)
// 姓名字典升序
arr.sortWith((user1, user2) => user1.name < user2.name)
//姓名字典降序
arr.sortWith((user1, user2) => user1.name > user2.name)

partition和span

partition将数组按照指定的规则分组 ,适用于 数组 List Map

val  list = List(1,2,3,4,5,6,7,8,9)
// 将集合根据条件分成两组返回一个存储集合的元组第一个集和实符合要求的元素
//(List(3, 6, 9),List(1, 2, 4, 5, 7, 8))
val res: (List[Int], List[Int]) = list.partition(x=>x%3==0)
//从第一个元素开始处理 配到不符合条件的就结束
list.span(_<3) // (List(1, 2),List(3, 4, 5, 6, 7, 8, 9))

val list2 = List("scala" , "is" , "option" , "fucntion")
// (List(scala, is, fucntion),List(option))
list2.partition(_.hashCode%2==0)
map集合******************************************
val map = Map("peiqi" -> 5, "jong" -> 3, "baji" -> 12)
// (Map(baji -> 12),Map(peiqi -> 5, jong -> 3))
val tuple: (Map[String, Int], Map[String, Int]) = map.partition(x=>x._1.contains("b"))
val tuple2: (Map[String, Int], Map[String, Int]) = map.partition(x=>x._2 >5)

grouped

将集合中的元素按照指定的个数进行分组

val  list1 = List(1,2,3,4,5,6,7,8,9)
val list2 = List("scala" , "is" , "option" , "fucntion")
val map = Map[String,Int]("peiqi" -> 5, "jong" -> 3, "baji" -> 12)
// 两个元素分成一组 ,9个元素总共分成5组
val res: Iterator[List[Int]] = list1.grouped(2)
var i = 0
// 遍历每个元素
res.foreach(list=>{
  i+=1
  list.foreach(x=>println(x+"----"+i))  // 打印每个元素和它所对应的组
})
// 将map集合按照个数进行分组
val res2: Iterator[Map[String, Int]] = map.grouped(2)
res2.foreach(i=>i.foreach(x=>println((x._1,x._2))))

groupBy

将集合中的数据按照指定的规则进行分组

序列集合

val  list1 = List(1,2,3,4,5,6,7,8,9)
val list2 = List("scala" , "is" , "option" , "fucntion")
 // 对序列数据进行分组
val res1: Map[Boolean, List[Int]] = list1.groupBy(x=>x>3) //HashMap(false -> List(1, 2, 3), true -> List(4, 5, 6, 7, 8, 9))
val res2: Map[Boolean, List[Int]] = list1.groupBy(x=>x%2==0)//HashMap(false -> List(1, 3, 5, 7, 9), true -> List(2, 4, 6, 8))
list2.groupBy(x=>x.hashCode%2==0)
//HashMap(false -> List(is, option, fucntion), true -> List(scala))
val res: Map[Boolean, List[String]] = list2.groupBy(x=>x.startsWith("s"))

键值映射集合分组

 val map = Map[String,Int]("peiqi" -> 5, "jong" -> 3, "baji" -> 12)
 val arr = Array(("cat",21),("lucy",33),("book",22),("jack",34))
// 按照key和value的内容分组
 println(map.groupBy(mp => mp._1))
 println(map.groupBy(mp => mp._2))
 
//  根据key 或者 value 分成两组  满足条件的和不满足条件的
 println(map.groupBy(mp => mp._1.hashCode%2==0))
 println(map.groupBy(mp => mp._2>2))

 // 对偶元组集合 和map的分组方式是一样的
 arr.groupBy(arr=>arr._1)
 arr.groupBy(arr=>arr._2)

reduce

底层调用的是reduceLeft , 从左边开始运算元素

val list = List(1,3,5,7,9)
// 每个元素累加  从左到右相加
val res1: Int = list.reduce(_+_)  // 25
//1-3)-5)-7)-9

val res2: Int = list.reduce(_ - _)  // -23
val arr = Array("haha", "heihei", "hehe")
// x 前面的元素  y 后面的元素  实现集合中字符串的拼接
val res3: String = arr.reduce((x, y) => x + " " + y) //haha heihei hehe
// 键值对元素的
val map = Map(("shaolin",88),("emei", 77),("wudang",99))
//(shaolin emei wudang,264)   key value分别做归约操作
val res4: (String, Int) = map.reduce((m1,m2)=>(m1._1+" "+m2._1 , m1._2+ m2._2))

reduceLeft和reduceRight

  val list = List(1, 3, 5, 7, 9)
  val arr = Array("a", "b", "c","d","e")
  val map = Map(("shaolin",88),("emei", 77),("wudang",99))
// 执行顺序是  1+3)+5)+7)+9
  val res1: Int = list.reduceLeft(_+_)
  // 1-3)-5)-7)-9
  val res01: Int = list.reduceLeft(_-_)
  val res2: String = arr.reduceLeft((a1, a2)=>a1+","+a2)
  val res3: (String, Int) = map.reduceLeft((m1,m2)=>(m1._1+" "+m2._1 , m1._2+ m2._2))
  println(res1)  //25
  println(res2) //a,b,c,d,e
  println(res3)//(shaolin emei wudang,264)

  val res11: Int = list.reduceRight(_+_) //  25
  // 执行顺序是  a,(b,(c,(d,e)))    a2  右边的最后一个元素
  val res12: String = arr.reduceRight((a1, a2)=>a1+","+a2)//a,b,c,d,e
  val res13: (String, Int) = map.reduceRight((m1,m2)=>(m1._1+" "+m2._1 , m1._2+ m2._2))//(shaolin emei wudang,264)
 // 5-(7-9)-->5-(7-9)-->3-(5-(7-9))-->1-(3-(5-(7-9)))
  val res14: Int = list.reduceRight(_-_)
  println(res14) // 5

  println(res11)  //25
  println(res12) //a,b,c,d,e
  println(res13)//(shaolin emei wudang,264)

// 字符串的拼接
arr.reduce(_ ++ _)
// 字符串的拼接
println(arr.reduce(_ ++"."++ _))

交集差集并集

val arr1 = Array(1, 3, 5, 7, 0)
val arr2 = Array(5, 7, 8, 9)
val res1: Array[Int] = arr1.intersect(arr2) // 交集 5 7
val res2: Array[Int] = arr1.diff(arr2) // 差集  1  3
// 单纯的合并两个元素中的数据
val res3: mutable.ArraySeq[Int] = arr1.union(arr2) // 1,3,5,7 ,5,7,8,9
// 在2.13.+中的union 被concat代替
val ints: Array[Int] = arr1.concat(arr2)
ints.foreach(println)
// 去除重复数据
val res4: mutable.ArraySeq[Int] = res3.distinct //,3,5,7,8,9

distinct和distinctBy

去除集合中的重复的元素 ,可以去除简单类型的数据, 也可以除去自定义的类型(底层依然是

hashcode和equals)
val arr1 = Array("a", "a","ab","cat" ,"hellocat" ,"hicat")
val newarr: Array[String] = arr1.distinct
newarr.foreach(println)
条件去重 
val arr1 = Array(new User("ls",21),new User("ls",22),new User("zss",21))
// 去除重名的重复数据
val res: Array[User] = arr1.distinctBy(x=>x.age)
res.foreach(x=> println(x.name))

zip

实现拉链式拼接, 只要操作的集合是迭代集合就可以拼接

val list1 = List("a" , "b" , "c" , "d")
val arr1 = Array(1,2,3,4)
val map  = Map[String,Int]("aa"->11,"cc"->22,"dd"->33)
// 以两个迭代集合中少的一方为基准对偶拼接List((a,1), (b,2), (c,3))
val res: List[(String, Int)] = list1.zip(arr1)
//ArraySeq((1,(aa,11)), (2,(cc,22)), (3,(dd,33)))
val res2: Array[(Int, (String, Int))] = arr1.zip(map)

zipWithIndex

简单理解为 遍历集合中的每个元素 , 将每个元素打上对应的索引值 , 组成元组(element , index) 返回新的集合 !

val list1 = List("a" , "b" , "c" , "d")
val arr1 = Array(1,2,3,4)
val map  = Map[String,Int]("aa"->11,"cc"->22,"dd"->33)
// List(((a,1),0), ((b,2),1), ((c,3),2), ((d,4),3))
list1.zip(arr1).zipWithIndex
//List((a,0), (b,1), (c,2), (d,3))
list1.zipWithIndex

fold,foldLeft 和foldRight

折叠是归约操作类似于reduce函数 ,但是fold函数中多出来一个初始值

val arr = Array("tom" , "cat" , "jim" , "rose")
// 遍历集合中的每个元素进行拼接  比reduce函数多出一个初始值
val res = arr.fold("hello")(_+" "+_)
val ls = List(1,3,5,7)
// 100+1)+3)+5)+7 底层调用的是  foldLeft
val res2 = ls.fold(100)(_+_)  // 116 
ls.foldLeft(100)(_+_) //  116

从右边开始运算 默认的值先参与运算进来

// 7-10)-->5-(-3)-->3-8 -->1-(-5)
val res01: Int = ls.foldRight(10)(_-_) //6

scan

一个初始值开始,从左向右遍历每个元素,进行积累的op操作

val arr = Array("cat" , "jim" , "tom")
// ArraySeq(hello, hello cat, hello cat jim, hello cat jim tom)
arr.scan("hello" )(_+" "+_)
val nums = List(1,2,3)
// List(10,10+1,10+1+2,10+1+2+3) = List(10,11,12,13)
val result = nums.scan(10)(_+_)   

mkString

将集合中的每个元素拼接成字符串

val arr = Array("a", "b", "c")
val str = arr.mkString
arr.mkString(" ")
arr.reduce(_+_)
arr.reduce(_+" "+_)

slice,sliding

slice(from: Int, until: Int): List[A] 提取列表中从位置from到位置until(不含该位置)的元素列表, 起始位置角标从0开始
slice

val arr = Array("a", "b", "c" ,"d","e","f")
arr.slice(0 ,2) // res0: Array[String] = ArraySeq(a, b)

sliding

sliding(size: Int, step: Int): Iterator[List[A]] 将列表按照固定大小size进行分组,步进为step,step默认为1,返回结果为迭代器
val nums = List(1,1,2,2,3,3,4,4)
// 参数一 子集的大小  参数二 步进
val res: Iterator[List[Int]] = nums.sliding(2,2)
res.toList // List(List(1, 1), List(2, 2), List(3, 3), List(4, 4))

take,takeRight,takeWhile

take 默认从左边开始取

val arr = Array("a", "b", "c" ,"d","e","f")
// 从左边获取三个元素 组成新的数组集合
arr.take(3)

takeRight 默认从右边开始取

val nums = List(1,1,1,1,4,4,4,4)
val right = nums.takeRight(4) // List(4,4,4,4)

takeWhile

// 小于4 终止 
nums.takeWhile(_ < 4)
val names  = Array ("cat", "com","jim" , "scala" ,"spark")
// 从左到右遍历符合遇到不符合条件的终止  储存在新的集合中
names.takeWhile(_.startsWith("c"))

Aggregate聚合

aggregate 方法是一个聚合函数,接受多个输入,并按照一定的规则运算以后输出一个结果值,在2.13+版本中被foldLeft取代!

集合间的转换函数

toArray 将其他类型的集合转换成数组
toList 将其他类型的集合转转成list
toSet 将其他类型的集合转换成Set
toSeq 将其他类型的集合转换成Seq序列
toMap 将对偶类型的集合转换成Map
toString 将其他类型转换成字符串

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值