简介
Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。对于几乎所有的集合类,Scala都同时提供了可变
和不可变
的版本。
可变集合可以在适当的地方被更新或扩展。这意味着你可以修改,添加,移除一个集合的元素。而不可变集合类,相比之下,永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变,所以这里的不可变并不是变量本身的值不可变,而是变量指向的那个内存地址不可变
可变集合和不可变集合,在scala中该如何进行区分呢?我们一般可以根据集合所在包名进行区分:
- scala.collection.
immutable
- scala.collection.
mutable
数组
不可变数组
object Scala01_Array {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 Array 不可变
//1. 数组的两种创建方式
//第一种
val array = new Array[String](5) // String [] array = new String [5]
//第二种
//val array = Array(1,2,3,4,5) // int[] array = new int[]{1,2,3,4,5}
//2.操作数组中的元素
array(0) = "大伟"
array(1) = "太海"
array(2) = "木海"
array(3) = "大海"
array(4) = "班长"
println(array)
//3.方法操作
array.update(4,"芳芳")
//val str: String = array.+("佳佳")
//println("str:" + str)
//val newArray: Array[String] = array.:+("佳佳")
val newArray: Array[String] = array :+ "佳佳"
println(newArray.mkString(" , "))
println(array eq newArray)
//val newArray1 = array.+:("佳佳")
val array1 = Array(1,2,3,4,5)
// 集合中:结尾的方法的运算顺序是从右往左
val newArray1 = 5 +: array1
println(newArray1.mkString(" , "))
//4. 迭代集合
// for(i <- array){
// println(i)
// }
println(array.mkString(", "))
}
}
可变数组
object Scala02_Array {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 ArrayBuffer 可变
//1. 数组的两种创建方式
val buffer = new ArrayBuffer[String]()
//val buffer1 = ArrayBuffer(1,2,3,4,5)
//2. 操作
//添加元素
buffer.append("zhangsan")
buffer.append("lisi")
buffer.append("wangwu")
buffer.append("zhaoliu","tianqi")
//插入元素
buffer.insert(1,"A","B")
//修改元素
buffer.update(1,"AAAA")
//删除元素
println(buffer.remove(1))
//删除多个
buffer.remove(0,2)
//3. 迭代
println(buffer.mkString(" "))
}
}
集合 可变与不可变的转换
object Scala03_Array {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 可变与不可变的转换
val array = Array(1,2,3,4,5) // 不可变
val buffer: ArrayBuffer[Int] = ArrayBuffer(4,5,6,7,8) //可变
// 不可变 -> 可变
val arraytoBuffer: mutable.Buffer[Int] = array.toBuffer
// 可变 -> 不可变
val buffertoArray: Array[Int] = buffer.toArray
//TODO 集合的迭代方法 foreach
val strings = Array("a","b","c","d","e")
// for
// mkString
// foreach
def myprint(str:String):Unit= {
println(str)
}
// strings.foreach(myprint)
strings.foreach((str:String)=>{println(str)})
strings.foreach((str:String)=>println(str))
strings.foreach((str)=>println(str))
strings.foreach(str=>println(str))
strings.foreach(println(_))
strings.foreach(print)
println()
// 数组的简单操作
// 多维数组
var myMatrix = Array.ofDim[Int](3,3)
myMatrix.foreach(list=>list.foreach(println))
// 合并数组
val arr1 = Array(1,2,3)
val arr2 = Array(4,5,6)
val arr6: Array[Int] = Array.concat(arr1, arr2)
arr6.foreach(println)
// 创建指定范围的数组
val arr7: Array[Int] = Array.range(0,2)
arr7.foreach(println)
// 创建并填充指定数量的数组
val arr8:Array[Int] = Array.fill[Int](5)(-1)
arr8.foreach(println)
}
}
Seq集合
Scala 集合 List 不可变
object Scala04_List {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 List 不可变
//1.创建list集合
val list = List(1,2,3,4,5)
//2.基本操作
val newList: List[Int] = list :+ 6
println(newList)
val newList2: List[Int] = 6 +: list
println(newList2)
// 获取元素
val result: Int = list(0)
println(result)
// 特殊集合
//println(Nil)
val nil: List[Nothing] = Nil
val newList3: List[Int] = 1::2::3::Nil
println(newList3)
val newList4: List[Any] = 1::2::3::list::Nil
println(newList4)
// 扁平化操作, 将一个集合拆分成一个一个的个体来使用
val newList5: List[Any] = 7::8::9::list:::Nil
println(newList5)
val newList6: List[Int] = list.updated(4,555)
println(newList6)
println(list eq newList6)
// 连接集合
val list1 = List(6,7,8,9)
val newList7: List[Int] = List.concat(list,list1)
println(newList7)
// 填充集合
val newList8: List[String] = List.fill[String](3)("a")
println(newList8)
}
}
Scala 集合 ListBuffer 可变
object Scala05_List {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 ListBuffer 可变
val buffer = new ListBuffer[String]
//val buffer1: ListBuffer[Int] = ListBuffer(1,2,3,4,5)
//基本操作
buffer.append("a","b","c")
println(buffer)
buffer.insert(1,"d","e","f")
println(buffer)
buffer.update(0,"aa")
buffer.remove(2)
println(buffer)
val buffer2: ListBuffer[Int] = ListBuffer(1,2,3)
val buffer3: ListBuffer[Int] = ListBuffer(4,5,6)
val buffer4: ListBuffer[Int] = buffer2 ++ buffer3
println(buffer4)
println(buffer2 eq buffer4) //false ++
val buffer5: ListBuffer[Int] = buffer2 ++= buffer3
println(buffer2 eq buffer5 ) // true ++=
var buffer6 = List(1,2,3,4) // 不可变
var buffer7 = ListBuffer(5,6,7,8) // 可变
//不可变 -> 可变
val buffer8: mutable.Buffer[Int] = buffer6.toBuffer
val buffer9: List[Int] = buffer7.toList
}
}
Set集合
不可变Set
object Scala06_Set {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 set 不可变
//val set: Set[Int] = Set(1,2,3,4,5,5,5,3,3,3)
//println(set)
// TODO Scala 集合 Set 可变
val set: mutable.Set[Int] = mutable.Set(1,2,3,4,5)
//基本操作
//println(set.add(6)) // true
//println(set.add(5)) // false
// update:
// 如果要更新的元素存在, true: 覆盖 false: 删除
// 如果要更新的元素不存在,true : 添加 false: 不添加
//set.update(6,false)
//set.remove(1)
val bool: Boolean = set.remove(6)
println(bool)
println(set)
val set1 = mutable.Set(1,2,3,4)
val set2 = mutable.Set(3,4,5,6)
// 交集
val set3: mutable.Set[Int] = set1 & set2 // Set(3,4)
println(set3)
// 差集
val set4: mutable.Set[Int] = set1 &~ set2 // Set(1,2)
println(set4)
}
}
Map集合
Map(映射)是一种可迭代的键值对(key/value)结构。所有的值都可以通过键来获取。Map 中的键都是唯一的。
Scala 集合 Map
object Scala07_Map {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 Map 不可变
//List(1,3,4,4)
//Set(1,3,4)
// 映射 A -> B
//val map: Map[String, Int] = Map("a"->1,"b"->2,"c"->3)
// TODO Scala 集合 Map 可变
val map: mutable.Map[String, Int] =
mutable.Map("a"->1,"b"->2,"c"->3)
//基本操作
//map.put("d",4)
//map.update("a",11)
//map.remove("a")
//println(map)
// 获取元素
// apply获取元素:如果key存在,正常获取,如果key不存在,直接抛出异常
//val value: Int = map.apply("d")
//println(value)
// Option: 避免空指针异常.
val option: Option[Int] = map.get("d")
// value.xxxx
if(!option.isEmpty){
val value: Int = option.get
println(value)
}else{
val value: Int = option.getOrElse(0)
println(value)
}
println(map.getOrElse("m", 100))
//Map 转换
val array: Array[(String, Int)] = map.toArray
println(array.mkString(" "))
val list: List[(String, Int)] = map.toList
println(list)
val set: Set[(String, Int)] = map.toSet
println(set)
}
}
元组
在Scala语言中,我们可以将多个无关的数据元素封装为一个整体,这个整体我们称之为:元素组合,简称元组。有时也可将元组看成容纳元素的容器,其中最多只能容纳22个
object Scala08_Tuple {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 Tuple
val tuple: (Int, String, String, Int) =
(1001,"zhangsan","beijing",30)
// 通过元素的顺序来获取
println(tuple._1)
println(tuple._2)
println(tuple._3)
println(tuple._4)
// tuple中最多放22个元素
// 通过索引获取元素
println(tuple.productElement(0))
// Map 和 Tuple的关系
// Map中的kv(键值对) ,实际上就是两个元素的tuple对象. 为此有个专门的叫法: 对偶元组
mutable.Map("a" -> 1)
//val tuple: (String, Int) = "b" -> 1
val map: mutable.Map[String, Int] =
mutable.Map(("a",1),("b",2),("c",3))
println(map)
for(t <- map){
println(t._1 + " : " + t._2)
}
println()
map.foreach(t=>println(t._1+" : " + t._2))
}
}
队列
object Scala09_Queue {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 队列
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())
}
}
Scala 集合 常用方法
object Scala10_Method {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 常用方法
val list = ListBuffer(1,2,3,4,5)
val list2 =ListBuffer(4,5,6,7,8,9,10,11)
//1.集合的长度
println(list.length)
println(list.size)
//2.集合是否为空
println(list.isEmpty)
//3.判断集合是否包含某个元素
println(list.contains(1))
//4.取集合的前几个元素/ 后几个元素
println(list.take(3))
println(list.takeRight(3))
//5.从集合中查找满足条件的第一个元素
def myfind(i:Int):Boolean={
i % 2 == 0
}
println(list.find(myfind))
println(list.find(_ % 2 == 0))
//6.丢弃前几个或者丢弃后几个元素
println(list.drop(2))
println(list.dropRight(2))
//7.反转集合
println(list.reverse)
//8.去重
// list.append(4,5,6,7)
//println(list)
//println(list.distinct)
//println(list.toSet)
//9. 集合头(集合的第一个元素)
println(list.head)
//10.集合尾(第一个元素后面的所有的元素)
println(list.tail) // tails -> 尾迭代
//11. 集合的最后一个元素
//list.reverse.head
println(list.last)
//12. 集合初始化
println(list.init) // inits -> 初始迭代
//13. 集合的并集
println(list.union(list2))
//14. 集合的交集
println(list.intersect(list2))
//15. 集合的差集
println(list.diff(list2))
}
}
object Scala11_Method {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 常用方法
val list = ListBuffer(1,2,3,4,5)
val list2 =ListBuffer(7,8,9,10,11,12)
// 16. 切分集合
println(list2.splitAt(3))
// 17. 滑动
println(list.sliding(2).mkString(" , "))
// 18. 滚动
println(list.sliding(2, 2).mkString(" , "))
// 19. 拉链
println(list.zip(list2))
// 20. 数据索引拉链
println(list2.zipWithIndex)
// 21. 最大值
println(list.max)
// 22. 最小值
println(list.min)
// 23. 求和
println(list.sum)
// 24. 求乘积
println(list.product)
val list3 = ListBuffer("a","b","c","ab","d")
println(list3.max)
println(list3.min)
}
}
object Scala12_Method {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 常用方法
val list = ListBuffer(1,2,3,4,5)
val list2 =ListBuffer(7,8,9,10,11,12)
// 25. 集合简化规约(reduce)
// (A1,A1) =>A1
//println(list.reduce((x: Int, y: Int) => {x + y}))
println(list.reduce( _ + _))
// 简化规约(左)
//println(list.reduceLeft(_ + _))
println(list.reduceLeft(_ - _)) // -8 -13
// 简化规约(右)
//println(list.reduceRight(_ + _))
println(list.reduceRight(_ - _)) //-2 -5(×) 3(√)
//26. 集合折叠
// (z: A1) : z => zero ,初始值
// (op: (A1, A1) => A1)
println(list.fold(6)(_ + _))
println(list.foldLeft(6)(_ + _))
println(list.foldRight(6)(_ + _))
println(list.foldRight(6)(_ - _))
println("========================")
// 27. 集合扫描(记录每次的计算结果)
println(list.scan(6)(_ + _))
println(list.scanLeft(6)(_ + _))
println(list.scanRight(6)(_ + _))
}
}
object Scala13_Method {
def main(args: Array[String]): Unit = {
// TODO Scala 集合 常用方法
val list = ListBuffer(1,2,3,4,5)
// 28. map: 映射, 将集合通过计算(转换规则)转换成另外一个集合.
var result = for(i <- list) yield {
"*" * i
}
println(result)
list.map((i:Int)=>{"*" * i})
println(list.map("*" * _))
// 29. flatten: 扁平化, 将集合中的整体(集合)拆分成一个一个的个体
var list2 = List(List(1,2),List(3,4))
// List(1,2,3,4)
println(list2.flatten)
val list3 = List(List(List(1,2)),List(List(3,4)))
println(list3.flatten.flatten)
val list4 = List("hello scala","hello spark")
// List("hello","scala","hello","spark")
println(list4.flatten)
// 30. flatMap: 集合扁平映射。
println(list4.flatMap(str => {str.split(" ")}))
println(list4.flatMap(_.split(" ")))
var list5 = List(List(1,2),List(3,4))
def myflatmap(ls:List[Int]):List[Int]={
ls.map(_ * 2 )
}
println(list5.flatMap(myflatmap))
//list5.flatMap(element=>element.map(_ * 2))
println(list5.flatMap(_.map(_ * 2)))
// 31. filter: 集合过滤数据, 按照指定的规则对集合中的元素进行过滤,
// 满足规则的数据保留,不满足规则的数据丢弃
val list6 = List(1,2,3,4)
// 过滤偶数
//println(list6.filter((i: Int) => {i % 2 == 0}))
println(list6.filter( _ % 2 == 0))
val list7 = List("hello","hello","scala","haha")
println(list7.filter(_.startsWith("h")))
val list8 = List("hello scala","hello spark")
println(list8.flatMap(_.split(" ")).filter(_.startsWith("s")))
// 32.groupBy: 分组, 按照指定的分组规则, 对集合中的元素进行分组, 返回的一个map,
// map的key就是分组规则计算的结果, map的value就是每组的数据(集合)
val list9 = List(1,2,3,4,5,6,7,8,9)
//按照集合元素对3取余的结果进行分组
println(list9.groupBy((i: Int) => {i % 3}))
val list10 = List("hello","hello","scala","haha","hive","scala","hello")
//按照单词分组
println(list10.groupBy(str => str))
//println(list10.groupBy(_ => {"haha"}))
//println(list10.groupBy(_))
//33. sortBy: 集合排序, 按照指定的排序规则将集合中的元素进行排序
val list11 = List(3,1,4,2)
//println(list11.sortBy((i: Int) => {i}))
println(list11.sortBy(i => i)) // 默认升序
println(list11.sortBy(i => -i)) // 降序
println(list11.sortBy(i=>i)(Ordering.Int.reverse))
val list12 = List((30,"zhangsan"),(20,"wangwu"),(20,"lisi"))
println (list12.sortBy(t=>t) {
Ordering.Tuple2(Ordering.Int.reverse, Ordering.String.reverse)
})
//34. sortWith: 自定义排序
val list13 = List((30,"zhangsan"),(20,"wangwu"),(20,"lisi"))
// 希望升序排序 left < right , 希望降序排序 left > right
println(list13.sortWith((left, right) => {
if (left._1 == right._1) {
left._2 > right._2
} else {
left._1 < right._1
}
}))
}
}
wordcount
object Scala14_Wordcount {
def main(args: Array[String]): Unit = {
// TODO Scala Wordcount TopN
// 需求: 从文件中读取数据, 将读取到的数据拆分成一个一个的单词,对每个单词出现的次数进行统计,
// 将最终统计的结果按照次数进行降序排序,取topn
// 1. 从文件中将数据读取到集合中
val source: BufferedSource = Source.fromFile("input/input.txt")
val dataList: List[String] = source.getLines().toList
source.close()
println("==>1." + dataList)
//List(hello world spark, hello scala hive, hive flume kafka hadoop, hello hadoop flume hbase)
//2. 将集合中的每个元素按照" "切分成一个一个的单词
val words: List[String] = dataList.flatMap(_.split(" "))
println("==>2." + words)
// List(hello, world, spark, hello, scala, hive, hive, flume, kafka, hadoop, hello, hadoop, flume, hbase)
//3. 将单词进行分组
val wordGroup: Map[String, List[String]] = words.groupBy(word=>word)
println("==>3." + wordGroup)
//Map(world -> List(world), kafka -> List(kafka), hadoop -> List(hadoop, hadoop), spark -> List(spark), hive -> List(hive, hive), scala -> List(scala), flume -> List(flume, flume), hello -> List(hello, hello, hello), hbase -> List(hbase))
//4. 将每组中的单词进行次数统计,转化成 K -> v (word,count)
val wordCount: Map[String, Int] = wordGroup.map(kv=>(kv._1,kv._2.length))
println("==>4." +wordCount)
//Map(world -> 1, kafka -> 1, hadoop -> 2, spark -> 1, hive -> 2, scala -> 1, flume -> 2, hello -> 3, hbase -> 1)
//5. 按照每个单词的次数进行排序,
//val finalwordCount: List[(String, Int)] =wordCount.toList.sortBy(kv=>{kv._2})(Ordering.Int.reverse)
val finalwordCount: List[(String, Int)] =wordCount.toList.sortBy(_._2)(Ordering.Int.reverse)
println("==>5." + finalwordCount)
//6. 取topn
val result: List[(String, Int)] = finalwordCount.take(3)
println("==>6." + result)
var result1 = dataList.
flatMap(_.split(" ")).
groupBy(word=>word).
map(kv=>(kv._1,kv._2.length)).
toList.sortBy(_._2)(Ordering.Int.reverse).
take(3)
println(result1)
}
}