一、集合
scala同时支持不可变集合和可变集合,默认采用不可变集合,包含三大类(Seq、Set、Map)
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable
元组Tuple
元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。
说的简单点,就是将多个无关的数据封装为一个整体,称为元组, 最大的特点灵活,对数据没有过多的约束。
注意:元组中最大只能有22个元素
// 声明
val tuple1 = (1, 2, 3, "hello", 4)
var tup1 = 2 -> “two”
var tup2 = 0 -> “zero”
// 访问
//访问元组的第一个元素 ,从1开始
println(tuple1 ._1)
// 遍历
for(item <- tuple1.productIterator){
println(item)
}
数组
// 声明定长数组
val arr01 = new Array[Int](4)
var arr02 = Array(1, 3, "xxx") // 本质是调用apply方法创建数组对象
// 声明变长数组
val arr2 = ArrayBuffer[Int]()
//追加值/元素
arr2.append(7)
//重新赋值
arr2(0) = 7
// 定长数组和变长数组的转化
arr01.toBuffer
arr2.toArray
列表(List)
Scala的List可以直接存放数据,就是一个object,默认情况下Scala的List是不可变的,List属于序列Seq
// 声明,创建时,直接分配元素
val list01 = List(1, 2, 3)
var list1 = List(1, 2, 3, "abc")
// :+运算符表示在列表的最后增加数据
val list2 = list1 :+ 4
println(list1) //list1没有变化
println(list2) //新的列表结果是 [1, 2, 3, "abc", 4]
// 从右向左的逻辑
val list5 = 4 :: 5 :: 6 :: list1 :: Nil // List(4, 5, 6, List(1, 2, 3, abc))
val list6 = 4 :: 5 :: 6 :: list1 // List(4, 5, 6, 1, 2, 3, abc)
val list7 = 4 :: 5 :: 6 :: list1 ::: Nil // List(4, 5, 6, 1, 2, 3, abc)
说明
符号::
表示向集合中 新建集合添加元素。
运算时,集合对象一定要放置在最右边,
运算规则,从右向左。
:::
运算符是将集合中的每一个元素加入到空集合中去
列表(ListBuffer)
ListBuffer是可变的list集合,可以添加,删除元素,ListBuffer属于序列
// 声明
val lst0 = ListBuffer[Int](1, 2, 3)
println("lst0(2)=" + lst0(2))
// 遍历
for (item <- lst0) {
println("item=" + item)
}
val lst1 = new ListBuffer[Int]
lst1 += 4
lst1.append(5)
lst0 ++= lst1
val lst2 = lst0 ++ lst1
val lst3 = lst0 :+ 5
println("=====删除=======")
println("lst1=" + lst1)
lst1.remove(1)
for (item <- lst1) {
println("item=" + item)
}
Map
Scala中不可变的Map是有序的,可变的Map是无序的
// 默认是不可变Map
val map1 = Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
// 1.从输出的结果看到,输出顺序和声明顺序一致
// 2.构建Map集合中,集合中的元素其实是Tuple2类型
// 可变Map
val map2 = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> 30)
// eg: 使用contains方法检查是否存在key
val map4 = mutable.Map( ("A", 1), ("B", 2), ("C", 3),("D", 30.9) )
if(map4.contains("B")) {
println("key存在 值= " + map4("B"))
} else {
println("key不存在")
}
// 取值方式:
// 1. 使用contains方法检查是否存在key ,然后使用map(key)
// 2. getOrElse()
val map4 = mutable.Map( ("A", 1), ("B", 2), ("C", 3),("D", 30.9) )
if( map4.contains("B") ) {
println("key存在 值= " + map4("B"))
} else {
println("key不存在")
}
// 增加元素
val map4 = mutable.Map(("A", 1), ("B", "北京"), ("C", 3))
val map5 = map4 + ("E"->1, "F"->3)
map4 += ("EE"->1, "FF"->3)
// 遍历
val map1 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) )
for ((k, v) <- map1) println(k + " is mapped to " + v)
for (v <- map1.keys) println(v)
for (v <- map1.values) println(v)
for(v <- map1) println(v)
Set集合
默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包
// 声明
val set01 = Set(1,2,4,"abc")
println(set01)
val set02 = mutable.Set(1,2,4,"abc")
println(set02)
set02.add(90)
set02 += 78
set02 -= 78
set02 += (90)
println(set02)
// 遍历
for (x <- set02) {
println(x)
}
二、常见算子操作
map映射操作
// 案例:请将List(3,5,7) 中的所有元素都 * 2 ,将其结果放到一个新的集合中返回,即返回一个新的List(6,10,14), 请编写程序实现.
// 1. 传统方式:
val list1 = List(3, 5, 7)
var list2 = ListBuffer[Int]()
for (item <- list1) { //遍历
list2.append(item * 2)
}
println(list2) // List(6, 10, 14)
// 2. scala 中的函数式编程解决方式
val list2 = list1.map(_*2)
println(list2) // List(6, 10, 14)
flatmap扁平化映射
flat即压扁,压平,扁平化,效果就是将集合中的每个元素的子元素映射到某个函数并返回新的集合。
// eg:
val names = List("Alice", "Bob", "Nick")
def upper( s : String ) : String = {
s. toUpperCase
}
println(names.flatMap(upper)) // List(A, L, I, C, E, B, O, B, N, I, C, K)
filter(过滤)
将符合要求的数据(筛选)放置到新的集合中
reduceLeft(化简,归约)
从左边开始执行将得到的结果返回给第一个参数,然后继续和下一个元素运行,将得到的结果继续返回给第一个参数,继续…
reduceRight
从右边开始执行将得到的结果返回给第2个参数,然后继续和前一个元素运行,将得到的结果继续返回给第一个参数,继续…
val list = List(1, 20, 30, 4, 5)
def sum(n1: Int, n2: Int): Int = {
n1 + n2
}
val res = list.reduceLeft(sum)
println("res=" + res)
folder(折叠)
fold函数将上一步返回的值作为函数的第一个参数继续传递参与运算,直到list中的所有元素被遍历。
可以把reduceLeft看做简化版的foldLeft,reduceLeft就是调用的foldLeft,默认从集合的head元素开始操作的
注意:foldLeft和foldRight 缩写方法分别是:/:和:\
val list = List(1, 2, 3, 4)
def minus( num1 : Int, num2 : Int ): Int = {
num1 - num2
}
println(list.foldLeft(5)(minus)) // 处理流程分析 ((((5-1)-2)-3)-4)
println(list.foldRight(5)(minus))// 处理流程分析 (1 -(2 -(3 - (4-5)))
val list4 = List(1, 9, 2, 8)
def minus(num1: Int, num2: Int): Int = {
num1 - num2
}
var i6 = (1 /: list4) (minus)
println(i6)
拉链(zip)
将两个集合进行 对偶元组合并,可以使用拉链
val list1 = List(1, 2 ,3)
val list2 = List(4, 5, 6)
val list3 = list1.zip(list2)
println("list3=" + list3)
并行(parallel)
// 并行打印
(1 to 5).foreach(println(_))
println()
(1 to 5).par.foreach(println(_))
wordcount经典案例
// 测试数据
val lines = List("atguigu liu hello ddd", "atguigu liu aaa aaa aaa ccc ddd uuu", "liu","ddd")
// 方案一
val res1 = lines.flatMap(_.split(" "))
println("res1=" + res1)
val res2 = res1.map((_, 1))
println("res2=" + res2)
val res3 = res2.groupBy(_._1)
println("res3=" + res3)
val res4 = res3.map(x=>(x._1, x._2.size))
println("res4=" + res4 )
val res5 = res4.toList.sortBy(_._2)
println("res5=" + res5)
val res6 = res5.reverse
// 方案二
var res7 = lines.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).mapValues(_.foldLeft(0)(_+_._2)).toList.sortBy(_._2).reverse
println("res7="+ res7)