(1) 获取集合长度
(2) 获取集合大小
(3) 循环遍历
(4) 迭代器
(5) 生成字符串
(6) 是否包含
注意:这些是集合类型的通用操作
总结:获取集合的长度使用lenght
方法,对于线性的序列都可以用lenght
方法来获取长度,但是像那种无序的集合,像Set
集合,就不能用lenght
方法,可以用size
方法,来获取大小。遍历的话可以用for循环,获取迭代器。或者foreach方法都可以。生成字符串,使用mkstring()
方法,这个方法非常好用。判断这个元素在集合中是否包含,使用contains()
方法,如果存在返回true,如果不存在返回false
package Scala03_shujujiegou
//这些是集合类型的通用的一些常用操作
class test11_tongyong {
}
object test11_tongyong{
def main(args: Array[String]): Unit = {
val list = List(6,9,6,89,99) //熟悉的列表
val set = Set(6,8,6,1) //Set集合,不关心这个有多长因为他根本是无序的,所以关心的是他的大小
//(1) 获取集合长度
println(list.length) //获取长度length方法,只要是线性的序列都可以用lenght方法,如果是那种无序的可以用size
//println(set.lenght) //对于某一些类型而言是没有lenght这个属性的,比如Set集合
println(set.size) //对于无序的用大小比较合适,
println("================")
//(2) 获取集合大小
println(list.size) //获取大小size方法
//(3) 循环遍历
for (i <- list){
println(i)
}
for (i <- 0 until list.length){
println(list(i))
}
println("============")
//(4) 迭代器
val iter = list.iterator //while循环的迭代器
while (iter.hasNext){
println(iter.next())
}
for (i <- list.iterator){ //for循环的迭代器
println(i)
}
//(5) 生成字符串
println(list.mkString(",")) //用字符串连接在一起mkString方法
//(6) 是否包含
println(list.contains(6)) //判断这个元素是否存在,contains方法。如果存在返回true,不存在返回false
}
}
说明:
(1) 获取集合的头
(2) 获取集合的尾 (不是头的都是尾)
(3) 集合最后一个数据
(4) 集合初始数据 (不包含最后一个)
(5) 反转集合
(6) 取前(后) n 个元素
(7) 去掉前(后) n 个元素
(8) 交集
(9) 并集
(10) 差集
(11) 拉链
(12) 滑窗
总结:大概分两种,一个集合的操作,和两个集合的操作
一个集合:
获取集合的头使用head
方法,也就是集合的第一个元素。获取集合的尾,使用tail
方法,注意除了头其他的元素都是尾。获取集合的最后一个元素,使用last
方法。获取集合的初始数据,使用init
方法,注意除了集合的最后一个元素,其他的元素都是初始数据。反转集合,使用reverse
方法,这个方法很常用。取集合的前几个元素或者后几个元素,使用take()
方法,里面的参数是取几个,取后几个元素用takeRight
方法,相当于从后面开始取,但是输出来的元素的顺序还是没变的。去掉前几个元素或者后面几个元素,使用drop()
方法,里面的参数是去掉几个元素,去掉后面几个元素使用dropRight()
方法。
两个集合的操作:
求两个集合的并集,使用union()
方法,里面的参数是要求并集的集合,注意如果是Set集合做并集的操作的话,那么会自动去重。两个集合的交集使用intersect()
方法。求两个集合的差集使用diff()
方法,里面的参数第二个集合,差集的意思是就是前面那个集合有的,第二个集合没有的元素,称之为差集。求两个集合的拉链,使用zip
方法,两个集合的拉链的意思是两个集合中的元素一一对应,然后返回一个二元组的形式。求集合的滑窗,这个是一个集合的操作,使用sliding()
方法,里面的参数是要每一个滑窗的元素个数,滑窗的意思是第一次输出123个元素,第二次输出的是234,这样依次滑下称之为滑窗,要是里面有两个参数的话,那么第二个参数就是步长
package Scala03_shujujiegou
//衍生集合方法
class test12_yansheng {
}
object test12_yansheng{
def main(args: Array[String]): Unit = {
val list = List(6,12,33,45,56)
val list2 = List(32,65,45,46,321)
// (1) 获取集合的头
println(list.head) //获取集合的头使用head方法,可迭代的类型都可以用,一般在有序的类型里面有,无序的不考虑头和尾
// (2) 获取集合的尾 (不是头的都是尾)
println(list.tail) //获取集合的尾用tail方法,注意除了头其他所有的元素都是尾
// (3) 集合最后一个数据
println(list.last) //获取集合的最后一个元素使用last方法
// (4) 集合初始数据 (不包含最后一个)
println(list.init) //init方法,除了最后一个元素,其他的元素都是初始数据
// (5) 反转集合
println(list.reverse) //reverse方法,将集合给翻转过来
// (6) 取前(后) n 个元素
println(list.take(3)) //取前几个元素用take方法
println(list.takeRight(3)) //取后几个元素,用takeRight方法,从右边开始取,顺序是不变的
// (7) 去掉前(后) n 个元素
println(list.drop(3)) //去掉前几个元素用drop方法
println(list.dropRight(3)) //全掉后几个元素用dropRight方法
//前面的都是一个集合做的操作,后面的时候基于两个集合做的操作
// (8) 并集
println("==============")
val union = list.union(list2) //求两个集合的并集也就是合在一起,使用union方法
println("并集:"+union)
println(list ::: list2) //获取使用 :::
//如果是set做并集。那么重复的数据会被去重
val set = Set(6,12,33,45,56)
val set2 = Set(32,65,45,46,321,6)
val union2 = set.union(set2)
println(union2)
println(set ++ set2)
println("===============")
// (9) 交集
val jiaoji = list.intersect(list2) //求两个集合的交集使用intersect方法
println(jiaoji)
// (10) 差集
val diff = list.diff(list2) //就是以前面那个表为基准,list里有的元素,list2里没有的元素就是差值
println(diff)
println("==============")
// (11) 拉链
//这个拉链的意思是两个集合里的元素一一对应,返回一个一个的二元组
println(list.zip(list2)) //两个集合的拉链使用zip方法,如果某一个集合多出来一个元素,那么就不显示那一个
// (12) 滑窗
//滑窗的意思是,第一次取123元素,第二次去234,每次取三个这样滑下去,每次取多少可以定义
println(list.sliding(3)) //滑窗使用sliding方法,里面的参数是每次滑的元素是几个,可以看到是一个迭代器
for(i <- list.sliding(3)){ //使用类似于迭代器的方式遍历出来
println(i)
}
println("================")
//要是里面有两个参数的话,第二个参数是步长,一个参数的时候默认步长是1
for(i <- list.sliding(3,2)){
println(i)
}
}
}
说明:
(1) 求和
(2) 求乘积
(3) 最大值
(4) 最小值
(5) 排序
总结:
求集合的和使用sum
方法,或者自己用增强for循环写,在外面定义一个变量初始值为0,然后进行累加。求集合里元素的乘积使用product
方法。求集合里元素的最大值使用max
方法。求集合里元素的最小值使用min
方法。排序使用sorted
方法,默认是升序,要是想降序的话,可以先排序,然后翻转列表,可以到达效果,
例如:println(list.sorted.reverse)
要是像是二元组什么的,默认是按照第一个参数排序,第一个参数是String类型的,第二个参数是Int类型的,要是想按照数字排序的话,那么就是用sortBy
方法
例如:println(list.sortBy(_._2))
还有第三种方法,sortWith
这个方法相当于Java里面的比较器
例如:println(list.sortWith((a,b) => {a如果aprintln(list.sortWith(_ < _))
package Scala03_shujujiegou
//集合常用简单计算函数
class test13_jiandanjisuan {
}
object test13_jiandanjisuan{
def main(args: Array[String]): Unit = {
val list:List[Int] = List(5,1,8,2,3,4)
val list2 = List(("a",2),("c",1),("f,3"),("b",8))
// (1) 求和
//自己用for循环写
var sum = 0
for (i <- list){
sum += i //sum初始值为0,依次取出list列表里的值相加,最后结果不就是总和嘛
}
println("list的和为:"+sum)
println(list.sum) //直接调用sum方法,直接就出来了
// (2) 求乘积
println(list.product) //求成绩使用product方法
// (3) 最大值
println(list.max) //求最大值使用max方法
// (4) 最小值
println(list.min) //求最小值使用min方法
// (5) 排序
//要做排序的话肯定是基于有序的集合类型才是有效的
//1,sorted
println(list.sorted) //这是升序,从小到大
println(list.sorted.reverse) //哈哈降序可以先排序然后翻转列表,可以达到效果
//传入隐式参数,降序排列 不传参数默认就是升序
//println(list.sorted(Ordered[Int]))
//2,sortBy
//像那种二元组第一个值是String类的第二个类型是Int类型的,直接println(sortBy(_._2))就可以了,
//3,sortWith 这个方法相当于java里的比较器
println("================")
println(list.sortWith((a,b) => {a<b})) //a小于b的时候不用交换,如果a大于b就交换
println(list.sortWith(_ < _ )) //可以直接简化成这个样子
}
}
(1) 过滤
遍历一个集合并从中获取满足指定条件的元素组成一个新的集合
(2) 转换/映射(map)
将集合中的每一个元素映射到某一个函数
(3) 扁平化 (flatten)
有点像两个列表要合并,列表里面还套着列表,我们要将他打散,这样的操作就叫做扁平化
(4) 扁平化+映射 注:flatMap
相当于先进行map操作,再进行flatten操作集合中的每个元素的子元素映射到某个函数并返回新的集合
(5) 分组(group)
按照指定的规则对集合的元素进行分组,分组是转换成了map
(6) 简化(reduce归约)
这个有点像reduce
(7) 折叠(fold)
总结:
1、过滤使用filter()
函数,里面的参数是一个函数,比如选取列表中的偶数可以写为:
val list2 = list1.filter(a => a % 2 == 0)
就可以将数组中所有的偶数筛选出来
2、映射使用map()
函数,比如将集合中的每个数*2,可以写为:
println(list1.map(a => a * 2))
3、扁平化使用flatten
函数,两个列表合并,列表中又嵌套了列表,将列表中的元素一个个拆开,然后合并成一个新的列表,比如:println(list1.flatten)
4、扁平映射,使用flatMap
函数,就是先映射然后进行扁平化,就是将一组单词进行分词,然后保存成新的列表,比如:
println(list1.flatMap(a => a.spilt(" ")))
//split函数使用空格分割单词,然后直接完成了映射扁平操作
5、分组使用groupBy()
函数,里面的参数也是一个函数,比如列表里面有奇数和偶数:
println(list.groupBy(_ % 2))
对2取余就只有两个结果一个是0,一个是1,然后就会自动分成两个组
再比如有一个需求,列表里都是单词,然后按照单词的首字母进行分组,首字母一样的都是一个组:
println(list.groupBy(a => a.charAT(0)))
//charAt取单词的某个字母,参数是索引,然后就完成了单词的首字母的分组
package Scala03_shujujiegou
//集合高级计算函数
class test14_gaojijisuan {
}
object test14_gaojijisuan{
def main(args: Array[String]): Unit = {
val list = List(1,2,3,4,5,6,7,8,9)
//1、过滤
//选取偶数
val evenlist = list.filter(a => a % 2 == 0) //这里面传入的是一个函数
val evenlist1 = list.filter(_ % 2 ==0 ) //可以简化成这样
println(evenlist) //取余为0那么都是偶数
println(evenlist1)
//取奇数
println(list.filter(_ % 2 == 1)) //可以直接不用赋值也可以
//2、map
//把集合中每个数乘2
println(list.map(_ * 2)) //传入的参数也是一个函数
println(list.map(a => a * a)) //这个是求平反方,这个就不能用_ * _了因为没有两个参数
println("================")
//3、扁平化
//列表合并,将每一个列表拆成一个一个的元素,这种操作就是扁平化
val list3:List[List[Int]] = List(List(1,2,3),List(4,5,6),List(6,7,8,9)) //这里这里面是list里面嵌套一个list
val flatlist =list3(0) ::: list3(1) ::: list3(2) //先用索引吧每一个列表取出来,然后用:::合并在一起
println(flatlist)
//flatten ,上面那种方式要是数据非常的多那么就非常麻烦一个一个写出来,flatten方法一下就出来了
val flatlist2 = list3.flatten //直接用flatten方法就完成了扁平化了
println(flatlist2)
println("=================")
//4、扁平映射
//将一组字符串进行分词,并保存成单词的列表
//split方法是java里面的,包装在scala里面就是Array[String]类型的一个数组。所以相当于用map函数进行了映射,将这个数组转化为List
val strings: List[String] = List("hello","word","scala","hello scala","hello java","we study")
val split:List[Array[String]] = strings.map(a => a.split(" ")) //使用split方法,空格拆分
val flattenList = split.flatten //首先经过映射之后,再调用flatten方法进行扁平化处理
println(flattenList)
println(split.flatten)
//有个更简单的操作,flatMap函数,直接包含了先映射再扁平的这两步操作
val flatmapList = strings.flatMap(a => a.split(" "))//相当于直接进行了转换然后在传入spilt操作
println(flatmapList)
println("==============")
//5、分组groupBy
//直接列表有奇数和偶数,直接分成两组
val groupMap = list.groupBy(_ % 2) //对2取余就只有两个结果嘛一个是0,一个是1,然后这两种结果分为两个组了
val groupMap2 = list.groupBy(a => { //用上面那个就行了
if(a % 2 ==0){
println("偶数")
}else{
println("奇数")
}
})
println(groupMap)
println(groupMap2)
//给定一组词汇,按照单词的首字母进行分组
val wordList = List("china","aex","alice","canda","cary","bob","japan")
println(wordList.groupBy(a => a.charAt(0))) //charAt方法取单词的首字母
}
}
(6) 简化(reduce归约)
sum都是一个归约操作,里面参数是两个相同类型的,最后最后结果就是一个数字
例如:println(list.reduce((a,b) => a * b))
(7) 折叠(fold)
折叠操作和reduce是一样的,有一个初始值,
例如:println(list.fold(10)(_ + _))
//然后初始值在前面 10 + 然后后面列表里的数依次相加
注意:reduce和fold折叠的区别就在于,fold有初始值,reduce没有初始值
package Scala03_shujujiegou
//高级计算函数
class test14_gajijisuan2 {
}
object test14_gajijisuan2{
def main(args: Array[String]): Unit = {
//reduce 类
val list = List(1,2,3,4,5,6,7,8,9)
//1、reduce (规约)
println(list.reduce((a,b) => a * b))//里面的参数是一个函数,其实sum就是一个规约操作,最后只剩下了一个数
val list2 = List(3,4,5,8,10)
println(list2.reduce(_ - _)) //默认是reduceLeft,跟reduceRight不一样
println(list2.reduceRight(_ - _)) //他这个结果是一个尾递归底层是这样的3-(4-(5-(8-10))) 结果就是-6
println("=======================")
//2、fold(折叠)
// 过程:10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9
println(list.fold(10)(_ + _)) //前面那个参数是初始值,后面那个参数是操作。比如数组加起来45然后加个10
println(list.foldLeft(10)(_ - _)) //10 - 1 -2 -3 -4 -5 -6 -7 -8 -9
println(list.foldRight(10)(_ - _)) // 1 -(2 -(3 -(4 -(5 -(6 -(7 -(8 -(9 -10))))))))) 先是 9 -10
}
}
思路:两个map合并,使用一个foldLeft()
方法,以其中一个map为初始值,基准,然后对第二个map里的每一个key,value进行遍历,使用getOrElse()
方法判断key是否在为基准的那个map里面存在,如果不存在返回一个初始值0,就直接添加进去,如果存在那么就进行累加,更新到基准的那个map里面去,两个map就合并了
注意:为基准的那个map一定要是mutable
可变的。第一个参数是初始值map2,然后第二个参数是一个函数,里面的第一个参数是map2的kv值,然后第二个参数是map1的kv值。然后函数体重定义两个变量遍历取出map1的kv值,然后判断一下map1的key是否在map2里面有,如果有那么就直接+value,就进行累加更新了,如果没有就相当于添加。最后函数的最后一行是返回值,返回map2的kv的那个参数就可以了
package Scala03_shujujiegou
import scala.collection.mutable
//应用案例1、合并Map
class test15_hebingmap {
}
object test15_hebingmap{
def main(args: Array[String]): Unit = {
val map1 = Map("a" -> 1,"b" -> 2,"c" -> 6)
val map2 = mutable.Map("a" -> 3,"b" -> 5, "c" -> 7,"d" -> 4) //要是map2为基准那么要是可变的随时改变
println(map1 ++ map2) //key都是相同的,就相当于是map2 覆盖了map1
//就我们大数据而言,同一个key可能有多个分区,按理说map1 和 map2 合并a 的次数应该是4,而不是map2覆盖map1
//我们可以以某一个map为一个起始的基准,然后再把另一个map里面的每一个value做一个遍历,
// 每一个key,value判断在不在基准的那个map里,如果不在的话直接添加,如果在的话就把
//当前的value都取出来,叠加之后再做一个更新操作
val map3 = map1.foldLeft(map2)((map11,map22) => { //map11是map1,map22是map2
val key = map22._1 //map2里面的key 比如 "a"
val value = map22._2 //map2里面的value 比如 3 就是次数
map11(key) = map11.getOrElse(key,0) + value getOrElse,设置一个初始值如果没有这个元素那么就返回这个初始值
map11
}) //因为这是一个键值对,返回的是一个二元组,所以得用foldLeft,因为底层是就是一个二元组所以用这个
println(map1)
println(map2)
println(map3)
}
}
1、需求
单词计数:将集合中出现的相同的单词,进行计数,取计数排名前三的结果
2、需求分析
3、案例示例
首先是定义字符串,第二步使用flatMap(a => a.split(" "))
方法,进行map映射,扁平化处理,使用空格进行分割。第三步,进行分组按到单词进行分组,一样的单词分到一个组。第四步,进行map转变,获取每个单词的长度,返回一个二元组的键值对,第一个是单词的key,第二个是单词的次数
第五步,使用toList
方法转变回list,然后进行排序,因为map是集合,里面是键值对,所以要转变回list
才能进行排序
package Scala03_shujujiegou
import scala.collection.mutable
class test3 {
}
object test3{
def main(args: Array[String]): Unit = {
//两个Map合并 案例
val map1 = Map("a" -> 3,"b" -> 6,"c" -> 7)
val map2 = mutable.Map("a" -> 1,"b" -> 2,"c" -> 4,"d" -> 5) //为基准的那个一定要是可变
val map3 = map1.foldLeft(map2)((map11,map22) => { //首先以map2为初始值,那么遍历的肯定的就是map1了
val key = map22._1 //这一步是在进行遍历,将map1的每一个key遍历
val value = map22._2
map11(key) = map11.getOrElse(key,0) + value //map11是map2的key和value的值,意思是key要是在map2里面存在那么就进行更新加value值
map11 //最后的返回值就是map2
})
println(map3)
println("==============")
//WordCount案例
//1、第一步定义字符串
val list = List("hello",
"word",
"hello word",
"hello scala",
"hello spark from scala",
"hello flink from scala"
)
//2、进行map,和扁平化,split 用空格进行分割
val list2 = list.flatMap(a => a.split(" "))
println(list2)
//3、进行进行分组
val list3 = list2.groupBy(word => word) //按照单词进行分组,一样的单词分到一组
println(list3)
//4、进行map转变,取每个单词的长度
val list4 = list3.map(kv => (kv._1,kv._2.length)) //进行map映射为一个二元组的,第一个参数是key,第二个是个数的长度
println(list4)
//5、转变回list,进行排序,map是一个集合是键值对不能进行排序,所以要转变回list
val list5 = list4.toList
println(list5.sortWith(_._2 > _._2).take(3)) //sortWith好进行降序,然后take取前三
}
}
package Scala03_shujujiegou
//复杂WordCount 案例
class test15_fuzaWordCount {
}
object test15_fuzaWordCount{
def main(args: Array[String]): Unit = {
val list = List(("hello",1),
("word",2),
("hello word",3),
("hello scala",2),
("hello spark from scala",3),
("hello flink from scala",5)
)
//思路一、直接展开为普通版本
val newStringList = list.map(
kv => (kv._1.trim + " ") * kv._2 //只有元组才有这个 ._1 获取元素方式
)
println(newStringList)
//接下来操作与普通版本完全一致
val list2 = newStringList.flatMap(a => a.split(" "))
println(list2)
val list3 = list2.groupBy(word => word) //按照按此进行分组
println(list3)
val list4 = list3.map(kv => (kv._1,kv._2.length)) //取key和单词的次数,
println(list4)
val list5 = list4.toList //转变为list 然后进行排序
println(list5.sortWith(_._2 > _._2).take(3))
}
}