Scala集合

Scala 同时支持不可变集合可变集合 ,因为不可变集合可以安全的并发访问 ,所以它也是默认使用的集合类库。在Scala 中,对于几乎所有的集合类,都提供了可变和不可变两个版本,具体如下:

不可变集合:集合内的元素、长度一旦初始化完成就不可再进行更改,任何对集合的改变都将生成一个新的集合。不可变集合都在 scala.collection.immutable 这个包下,使用时无需手动导包。

可变集合:指的是这个集合本身可以动态改变,且可变集合提供了改变集合内元素的方法。可变集合都在scala.collection.mutable 这个包下,使用时需要手动导包。

4.1. 结构树

蓝色为特质(接口),黑色为实现类

4.2. Traversable

4.2.1. 语法格式

复制代码
创建空的Traversale
    val t1 = Traversable.empty[Int]
    val t2 = Traversable[Int]()
    val t3 = Nil
    创建带元素的Traversable对象
    val t4 = List(1,2,3).toTraversable List为默认实现类
    val t5=Array(1,2,3).toTraversable
    val t6 = Set(1,2,3).toTraversable

    通过Traversable伴生对象apply方式实现
    val t7 = Traversable(1,2,3)

4.2.2. 转置集合transpose

复制代码
 val t8 = Traversable(Traversable(1,2,3),Traversable(4,5,6),Traversable(7,8,9))
  val result1 =t8.transpose
  println(result1)
  List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9))

4.2.3. 拼接集合 Traversable.concat(x,x,x)

复制代码
  已知有三个 Traversable 集合,分别存储 (11, 22, 33), (44, 55), (66, 77, 88, 99) 元素
  通过 concat 方法拼接上述三个集合
  将拼接后的结果打印到控制台
  val t9 = List(11,22,33).toTraversable
  val t10 = List(44,55).toTraversable
  val t11 = Traversable(66,77,88,99)
  val result2 = Traversable.concat(t9,t10,t11)
  println(result2)
  List(11, 22, 33, 44, 55, 66, 77, 88, 99)拼接成一个集合

4.2.4. 计算阶乘

复制代码
val t12 = Traversable(1,2,3,4,5)
  val result3 = t12.scan(1)(_*_)
  scan(1)代表起始值为1
  完整scan(1)((x:Int,y:Int)=>x*y)
  println(result3)
  List(1, 1, 2, 6, 24, 120)
  1*1   1*2  2*3  6*4  24*5
  从左往右
  val result4 = t12.scanLeft(1)(_*_)
  从右往左
  val result5 = t12.scanRight(1)(_*_)

4.2.5. 获取元素

head :获取集合的第一个元素,如果元素不存在,则抛出 NoSuchElementException 异常

last :获取集合的最后一个元素,如果元素不存在,则抛出 NoSuchElementException 异常

headOption :获取集合的第一个元素,返回值类型是 Option

lastOption :获取集合的最后一个元素,返回值类型是 Option

find :查找集合中第一个满足指定条件的元素

slice :截取集合中的一部分元素(左闭右开)

需求:

定义一个 Traversable 集合,包含 1, 2, 3, 4, 5, 6

分别通过 head、last、headOption、lastOption 获取集合中的首尾元素

通过 find 方法获取集合中第一个偶数

通过 slice 方法获取 3, 4, 5 并将它们放到一个新的 Traversable 集合

复制代码
val t13 = Traversable(1,2,3,4,5,6)
  println(t13.head,t13.last,t13.headOption.getOrElse(0),t13.lastOption.getOrElse(0))
  getOrElse(0)如果不存在就返回0
  (1,6,Some(1),Some(6))
   val result6= t13.find(_ % 2 == 0)
  (x)=>{x%2==0}
  println(result6)
  Some(2)
  val result7=t13.slice(2,5)
  println(result7)
  List(3, 4, 5)

4.2.6. 判断元素

def forall(p: (A) => Boolean): Boolean

如果集合中所有元素都满足指定的条件则返回 true,否则返回 false

def exists(p: (A) => Boolean): Boolean

只要集合中任意一个元素满足指定的条件就返回 true,否则返回 false

需求:

定义一个 Traversable 集合,包含 1, 2, 3, 4, 5, 6

通过 forall 方法判断集合中的元素是否都是偶数

通过 exists 方法判断集合中的元素是否有偶数

复制代码
  val t14 = Traversable(1,2,3,4,5,6)
  val result8 = t14.forall(_%2==0)
  val result9 = t14.exists(_%2==0)
  println(result8,result9)
  (false,true)

4.2.7. 聚合操作

count :统计集合中满足条件的元素个数

sum :获取集合中所有的元素和

product :获取集合中所有的元素乘积

max :获取集合中所有元素的最大值

min :获取集合中所有元素的最小值

需求:

定义一个 Traversable 集合,包含 1, 2, 3, 4, 5, 6

通过 count 方法统计集合中所有奇数的个数

通过 sum 方法获取集合中所有元素的和

通过 product 方法获取集合中所有元素的乘积

通过 max 方法获取集合中所有元素的最大值

通过 min 方法获取集合中所有元素的最小值

复制代码
 val t15 = Traversable(1,2,3,4,5,6)
  val result10 = t15.count(_%2==1)
  val result11 = t15.sum
  val result12 = t15.product
  val result13 = t15.max
  val result14 = t15.min
  println(result10,result11,result12,result13,result14)
  (3,21,720,6,1)

4.2.8. 类型转换

toXxx() 方法(toList, toSet, toArray, toSeq 等)。

需求:

定义一个 Traversable 集合,包含 1, 2, 3, 4, 5, 6

将集合分别转成数组、列表、集这三种形式,并打印结果

复制代码
  val t16 = Traversable(1,2,3,4,5,6)
  val resultArray = t16.toArray
  val resultList = t16.toList
  val resultSet = t16.toSet
  println(resultArray,resultList,resultSet)
  ([I@57855c9a,List(1, 2, 3, 4, 5, 6),Set(5, 1, 6, 2, 3, 4))

4.2.9. 填充元素

fill :快速生成指定数量的元素,并放入集合中

iterate :根据指定的条件,生成指定数量的元素,并放入集合中

range :生成某个区间内指定间隔的元素,并放入集合中

需求:

通过 fill 方法,生成一个 Traversable 集合,该集合包含 5 个元素,都是"abc"

通过 fill 方法,生成一个 Traversable 集合,该集合包含 3 个随机数

通过 fill 方法,生成一个 Traversable 集合,该集合包含 5 个元素,都是 List("abc", "abc") 集合

通过 iterate 方法,生成一个 Traversable 集合,该集合包含 5 个元素,分别为:1, 10, 100, 1000, 10000

通过 range 方法,获取从数字 1 开始到数字 21 结束,间隔为 5 的所有数据

复制代码
println(Traversable.fill(5)("abc"))
  List(abc, abc, abc, abc, abc)
  println(Traversable.fill(3)(Random.nextInt(100)))一百以内的随机整数
  List(62, 71, 37)
  println(Traversable.fill(5,2)("abc"))
   5 表示生成的集合中有 5 个集合元素,2 表示每个集合元素的长度为 2
  List(List(abc, abc), List(abc, abc), List(abc, abc), List(abc, abc), List(abc, abc))
  println(Traversable.iterate(1,5)(x=>x*10))
  List(1, 10, 100, 1000, 10000)
  println(Traversable.range(1,21,5))左闭右开
  List(1, 6, 11, 16)

4.3. Iterable

4.3.1. 遍历

Traversable 提供了两种遍历数据的方式:

通过 iterator() 方法实现,迭代访问元素。这种方式属于主动迭代,可以通过 hasNext() 检查是否还有元素,且可以主动的调用 next() 方法获取元素。即:我们可以自主控制迭代过程。

通过 foreach() 方法实现,遍历访问元素。这种方式属于被动迭代,只需要提供一个函数,并不能控制遍历的过程。即:迭代过程是由集合本身控制的。

需求:

定义一个 Traversable 集合,包含 1, 2, 3, 4, 5

通过 iterator() 方法遍历上述列表

通过 foreach() 方法遍历上述列表

复制代码
val t17 = Traversable(1,2,3,4,5,6)
   val iterator: Iterator[Int] = t17.toIterator
  while(iterator.hasNext){
    print(iterator.next())
  }
  123456
 println()
  val result15 = t17.foreach(print)
  foreach(x=>println(x))
  123456

  println()

4.3.2. 分组遍历

def grouped(size: Int): Iterator[Ierable[A]]

需求:

定义一个 Iterable 集合,存储 1~13 之间的所有整数

通过 grouped() 方法,对 Iterator 集合按照 5 个元素为一组的形式进行分组,遍历并打印结果

复制代码
val t18= (1 to 13).toIterable
val result16 = t18.grouped(5)每组5个
  result16.foreach(print(_))
  Vector(1, 2, 3, 4, 5)Vector(6, 7, 8, 9, 10)Vector(11, 12, 13)
  println()

4.3.3. 按索引生成元组

需求:

定义一个 Iterable 集合,存储 "A", "B", "C", "D", "E"

通过 zipWithIndex() 方法按照 字符串 -> 索引 生成新的集合

将上一步结果通过 map() 方法再按照 索引 -> 字符串 生成新的集合

复制代码
 val t19 = ('A' to 'E').toIterable
  val result17 = t19.zipWithIndex
  println(result17)
  Vector((A,0), (B,1), (C,2), (D,3), (E,4))
  val result18 = result17.map(x=>x._1->x._2)
  println(result18)
  Vector((A,0), (B,1), (C,2), (D,3), (E,4))

4.3.4. 判断集合是否相同

需求:

定义 Iterable 集合 iter1,包含 "A", "B", "C"

通过 sameElements() 方法,判断集合 iter1 和 Iterable("A", "B", "C") 是否相同

通过 sameElements() 方法,判断集合 iter1 和 Iterable("A", "C", "B") 是否相同

定义 Iterable 集合 iter2,包含 "A", "B", "C", "D"

通过 sameElements() 方法,判断集合 iter1 和 iter2 是否相同

思考:HashSet(1, 5, 2, 3, 4) 和 TreeSet(2, 1, 4, 3, 5) 是否相同?

复制代码
val t20 = Iterable("A" ,"B", "C")
   通过 sameElements() 方法,判断集合 iter1 和 Iterable("A", "B", "C") 是否相同
     println(t20.sameElements(Iterable("A", "B", "C")))  true
      通过 sameElements() 方法,判断集合 iter1 和 Iterable("A", "B", "C") 是否相同
     println(t20.sameElements(Iterable("A", "C", "B")))  false
      定义 Iterable 集合 iter2,包含 "A", "B", "C", "D"
     val iter2 = Iterable("A", "B", "C", "D")
      通过 sameElements() 方法,判断集合 iter1 和 iter2 是否相同
     println(t20.sameElements(iter2))  false
      思考:HashSet(1, 5, 2, 3, 4) 和 TreeSet(2, 1, 4, 3, 5) 是否相同?
     println(mutable.HashSet(1, 5, 2, 3, 4).sameElements(mutable.TreeSet(2, 1, 4, 3, 5)))
  true
  false
  false
  true

4.4. Seq

4.4.1. Set

HashSet:HashSet 是基于 HashMap 实现的,对 HashMap 做了一层简单的封装,而且只使用了HashMap 的 Key 来实现各种特性。元素特点唯一、无序。

ListSet:元素特点唯一、有序(元素添加的顺序)。

TreeSet:元素特点唯一、排序(按自然顺序排序)。

需求:

创建 HashSet 集合,存储元素 1, 4, 3, 2, 5, 5,然后打印集合

创建 ListSet 集合,存储 1, 4, 3, 2, 5, 5,然后打印集合

创建 SortedSet 集合,存储元素 1, 4, 3, 2, 5, 5,然后打印集合

复制代码
 val hashSet1 = HashSet(1,4,3,2,5,5)
  val listSet1 = ListSet(1,4,3,2,5,5)
  val sortSet1 = SortedSet(1,4,3,2,5,5)
  println(hashSet1,listSet1,sortSet1)
  (Set(5, 1, 2, 3, 4),ListSet(1, 4, 3, 2, 5),TreeSet(1, 2, 3, 4, 5))

4.4.2. Map

HashMap:元素特点 Key 唯一、无序。

ListMap:元素特点 Key 唯一、有序(元素添加(存储)的顺序)。

TreeMap:元素特点 Key 唯一、排序(按自然顺序排序)。

需求:

创建 HashMap 集合,存储元素 ("A", 1), ("B", 2), ("C", 3), ("C", 3),然后打印集合

创建 ListMap 集合,存储 ("A", 1), ("C", 3), ("B", 2), ("C", 3),然后打印集合

创建 TreeMap 集合,存储元素 ("A", 1), ("C", 3), ("B", 2), ("C", 3),然后打印集合

复制代码
val hashMap1 = HashMap(("A"-> 1), ("B"-> 2), ("C"-> 3), ("C"->3))
val listMap1 = ListMap(("A", 1), ("C", 3), ("B", 2), ("C", 3))
val treeMap1 = TreeMap(("A", 1), ("C", 3), ("B", 2), ("C", 3))
println(hashMap1,listMap1,treeMap1)
  (Map(A -> 1, B -> 2, C -> 3),ListMap(A -> 1, B -> 2, C -> 3),Map(A -> 1, B -> 2, C -> 3))

4.5. 数组Array

分为可变数组和不可变数组

4.5.1. 不可变数组

数组的长度不允许改变,数组的内容可以改变。

复制代码
  val|var 数组名 = new Array[元素类型](数组长度)
  new的数组()写的是长度
  val|var 数组名 = Array(元素1, 元素2, 元素3, ...)`
  非new的数组()写的是元素

需求:

定义一个长度为 10 的整型数组,设置第 1 个元素为 5,设置第 2 个元素为 10,并打印这两个元素

定义一个包含 Java,Scala,Python 三个元素的数组,并打印数组长度

复制代码
  val arr1 = new Array[Int](10)
  arr1(0)=5
  arr1(1)=10
  arr1.foreach(print)
  println()
  51000000000

4.5.2. 可变数组

数组的长度和内容都是可变的,可以往数组中添加、删除元素。

复制代码
  val|var 变量名 = ArrayBuffer[元素类型]()
  val|var 变量名 = ArrayBuffer(元素1, 元素2, 元素3, ...)

需求:

定义一个长度为 0 的整型变长数组

定义一个包含 Hadoop、Hive、Spark 三个元素的变长数组

复制代码
val arr2 = ArrayBuffer[Int](0)
  println(arr2)
  val arr3 = ArrayBuffer[String]("Hadoop","Hive","Spark")
  arr3.foreach(println)
  ArrayBuffer(0)
  Hadoop
  Hive
  Spark

4.5.3. 增删改

针对可变数组

+= :添加单个元素

-= :删除单个元素

++= :追加多个元素到变长数组中

--= :移除变长数组中的多个元素

数组名(索引) = 新值 或者 数组名.update(索引, 新值) :修改元素

vb 复制代码
`val arr4 = ArrayBuffer("Hadoop","Hive","Spark")
  arr4+="Scala"
  println(arr4)
  arr4-="Hadoop"
  println(arr4)
  arr4++=Array("Linux","zookeeper")
  println(arr4)
  arr4--=Array("Scala","Linux")
  println(arr4)
  arr4 ++= ArrayBuffer("Phoenix", "Sqoop")
  println(arr4)
  arr4.update(1,"123")
  println(arr4)
  arr4(2)="234"
  ArrayBuffer(Hadoop, Hive, Spark, Scala)
  ArrayBuffer(Hive, Spark, Scala)
  ArrayBuffer(Hive, Spark, Scala, Linux, zookeeper)
  ArrayBuffer(Hive, Spark, zookeeper)
  ArrayBuffer(Hive, Spark, zookeeper, Phoenix, Sqoop)
  ArrayBuffer(Hive, 123, zookeeper, Phoenix, Sqoop)`

4.5.4. 遍历数组

val arr5 = Array(1, "2", 3.14, true, null)

遍历元素

复制代码
for(i<-arr5){
    println(i)
  }
  遍历索引
  for(i<-arr5.indices){
    println(i)
  }
  to 或 until
  for(i <- 0 to arr5.size){
    println(i)
  }
  arr5.foreach(println)

4.5.5. 常用方法

sum() :求和。

max() :求最大。

min() :求最小。

sorted() :排序(正序),返回一个新的数组。倒序可以先排序再反转。

reverse() :反转,返回一个新的数组。

复制代码
var arr6=Array(4,1,3,2,5)
  println(arr6.sum)
  println(arr6.max)
  println(arr6.min)
  arr6.sorted.foreach(print)
  println
  arr6.sorted.reverse.foreach(print)
  println
  15
  5
  1
  12345
  54321

4.6. 元组Tuple

元组的长度和元素都是不可变的。

复制代码
val|var 元组名 = (元素1, 元素2, 元素3, ...)
val|var 元组名 = 元素1 -> 元素2

注意:格式二只适用于元组中只有两个元素的情况

需求:

定义一个元组,包含学生的姓名和年龄

分别使用小括号以及箭头的方式来定义元组

复制代码
val tuple1 = ("a",1,"123",true,false)
  println(tuple1)
  val tuple2 = "一个人"->12
  println(tuple2)
  (a,1,123,true,false)
  (一个人,12)

4.6.1. 访问元素

复制代码
元组名._n
  val tuple3 = ("a",1,"123",true,false)
  println(tuple3._1,tuple3._5)
  (a,false)

4.7. 列表List

有序,可重复。

4.7.1. 不可变列表

列表的元素、长度都是不可变的。

复制代码
val|var 列表名 = List(元素1, 元素2, 元素3, ...)
val|var 列表名 = Nil
val|var 列表名 = 元素1 :: 元素2 :: 元素n :: Nil

需求:

创建一个不可变列表,存放元素

使用 Nil 创建一个不可变的空列表

使用 :: 方法创建列表,包含 -2、-1 两个元素

复制代码
val list1 = List(1,2,3,4,5)
  val list2 = Nil
  val list3 = -1 :: -1 :: 2 :: Nil
  println(list3)
  List(-1, -1, 2)

4.7.2. 可变列表

可变列表指的是列表的元素、长度都是可变的。

复制代码
val|var 列表名 = ListBuffer[数据类型]()
val|var 列表名 = ListBuffer(元素1, 元素2, 元素3, ...

需求:

创建空的整型可变列表

创建一个可变列表,初始化时包含 1, "2", 3.14, true, null 元素

复制代码
 val list4 = ListBuffer[Any]()
  val list5 = ListBuffer(1, "2", 3.14, true, null)

4.7.3. 常用方法

列表名(索引) 根据索引(索引从0开始),获取列表中的指定元素

列表名(索引) = 值 修改元素值

+= 添加单个元素

++= 追加多个元素到可变列表中

-= 删除单个元素

--= 移除可变列表中的多个元素

toList 将可变列表(ListBuffer)转换为不可变列表(List)

toArray 将可变列表(ListBuffer)转换为不可变数组(Array)

toBuffer 将可变列表(ListBuffer)转换为可变数组(BufferArray)

val list6 = ListBuffer[Int]()

list6+=123

list6.toList+=1 显然这样会报错,因为不可变列表不可添加和修改元素

println(list6)

需求:

定义一个列表 list1,包含以下元素: 1, "2", 3.14, true, null

使用 isEmpty 方法判断列表是否为空,并打印结果

再定义一个列表 list2,包含以下元素: "a", "b", "c"

使用 ++ 将两个列表拼接起来,并打印结果

使用 head 方法,获取列表的首个元素,并打印结果

使用 tail 方法,获取列表中除首个元素之外的其他所有元素,并打印结果

使用 reverse 方法,将列表元素反转,并打印结果

使用 take 方法,获取列表中的前缀元素,并打印结果

使用 drop 方法,获取列表中的后缀元素,并打印结果

使用 update 方法,修改指定位置元素,并返回一个修改后的新集合

复制代码
val list7 = List(1, "2", 3.14, true, null)
  println(list7.isEmpty)
  val list8 = List("a", "b", "c")
  println(list7 ++ list8)
  println(list7.head)
  println(list7.tail)
  println(list7.reverse)
  println(list7.take(3))前3个数
  println(list7.drop(4))除了前4个数
  println(list7.updated(0, "abc"))
false
  List(1, 2, 3.14, true, null, a, b, c)
  1
  List(2, 3.14, true, null)
  List(null, true, 3.14, 2, 1)
  List(1, 2, 3.14)
  List(null)
  List(abc, 2, 3.14, true, null)

4.7.4. 扁平化

嵌套列表中的每个元素单独放到一个新的列表中。

需求:

定义一个列表,该列表有三个元素,分别为: List("Hello", "World") 、 List("Hello", "Scala") 、

List("Hello", "Spark")

使用 flatten 将这个列表转换为 List("Hello", "World", "Hello", "Scala", "Hello", "Spark")

复制代码
val list9 =  List(List("Hello", "World") ,List("Hello", "Scala"), List("Hello", "Spark"))
  println(list9.flatten)
  List(Hello, World, Hello, Scala, Hello, Spark)

4.7.5. 拉链与拉开

将两个列表合并成一个列表,列表的元素为元组。无法组成拉链的单个元素会被丢弃

将一个列表拆分成两个列表,两个列表被元组包含

需求:

定义列表 names,保存三个学生的姓名,分别为:张三、李四、王五

定义列表 ages,保存学生的年龄,分别为:18、19、20

使用 zip 将列表 names 和 ages 合并成一个列表 list

使用 unzip 将列表 list 拆分成包含两个列表的元组 tuple

复制代码
 val names = List("张三","李四","王五")
  val ages = List(18,19,20)
  val list= names.zip(ages)
  println(list)
  println(list.unzip)
  List((张三,18), (李四,19), (王五,20))
  (List(张三, 李四, 王五),List(18, 19, 20))

4.7.6. 转换字符串

toString :返回 List 中的所有元素的字符串

mkString :可以将元素以指定的分隔符拼接起来并返回,默认没有分隔符

需求:

定义一个列表,包含元素:1, 2, 3, 4

使用 toString 方法输出该列表元素

使用 mkString 方法指定分隔符为冒号,并输出该列表元素

复制代码
var list10 = (1 to 4).toList
  println(list10.toString())
  println(list10.mkString(":"))
  List(1, 2, 3, 4)
  1:2:3:4

4.7.7. 交集/并集/差集

union并集(合并)操作,且不去重

intersect :表示对两个列表取交集(相同)

diff :表示对两个列表取差集(不同)

需求:

定义列表 list1,包含以下元素:1, 2, 3, 4

定义列表 list2,包含以下元素:3, 4, 5, 6

使用 union 获取 list1 和 list2 的并集

在上一步的基础上,使用 distinct 去除重复的元素

使用 intersect 获取 list1 和 list2 的交集

使用 diff 获取列表 list1 和 list2 的差集

复制代码
var list11 = List(1,2,3,4)
  var list12 = List(3,4,6,5)
  println(list11.union(list12))
  println(list11.union(list12).distinct)
  println(list11.intersect(list12))
  println(list11.diff(list12))
  List(1, 2, 3, 4, 3, 4, 6, 5)
  List(1, 2, 3, 4, 6, 5)
  List(3, 4)
  List(1, 2)

4.8. 集Set

唯一,自动去重。

4.8.1. 不可变集

元素和长度都不可变

val|var 集名 = Set[类型]()

val|var 集名 = Set(元素1, 元素2, 元素3, ...)

需求:

定义一个空的整型不可变集

定义一个不可变集,保存以下元素:1, 1, 2, 3, 4, 5

复制代码
var set1 = Set(1,1,2,3,4,5)
  println(set1)

4.8.2. 可变集

元素和长度都可变

val|var 集名 = mutable.Set[类型]()

val|var 集名 = mutable.Set(元素1, 元素2, 元素3, ...)

需求:

定义一个可变集,包含以下元素:1, 2, 3, 4

添加元素 5 到可变集中

添加元素 6, 7, 8 到可变集中

从可变集中移除元素 3

从可变集中移除元素 3, 5, 7

复制代码
var set2 = mutable.Set(1, 2, 3, 4)
  set2+=5
  println(set2)
  set2++=List(6,7,8)
  println(set2)
  set2-=3
  println(set2)
  set2--=Array(3,4,5)
  println(set2)
  Set(5, 1, 2, 3, 4)
  Set(5, 1, 2, 3, 4)
  Set(5, 1, 6, 2, 7, 3, 8, 4)
  Set(5, 1, 6, 2, 7, 8, 4)
  Set(1, 6, 2, 7, 8)
  set2.update(2,false)删除
  set2.update(10,true)添加
  println(set2)
  Set(1, 2, 6, 7, 8)
  Set(1, 6, 10, 7, 8)

4.8.3. 语法格式 功能

4.9. 映射 Map

如果添加相同键元素,则后者的值会覆盖前者的值。

4.9.1. 不可变Map

Map 的元素、长度都是不可变的。

复制代码
val|var map = Map(键1 -> 值1, 键2 -> 值2, 键3 -> 值3, ...)
  val|var 集名 = Map((键1, 值1), (键2, 值2), (键3, 值3), ...)

需求:

定义一个 Map,包含以下元素: "张三" -> 18 , "李四" -> 19 , "王五" -> 20

获取键为张三的值

复制代码
  var map1 = Map("张三"-> 18,"李四"->19,"王五"->20)
  var map2 = Map(("张三",18),("李四",19),("王五",20))
  println(map1("张三"))
  println(map2("李四"))
  println(map1.getOrElse("zs","不存在"))
  18
  19
  不存在

4.9.2. 可变Map

需求:

定义一个 Map,包含以下元素: "张三" -> 18 , "李四" -> 19 , "王五" -> 20

获取键为张三的值

修改张三的年龄为 28

复制代码
  var map3 = mutable.Map("张三" -> 18, "李四" -> 19, "王五" -> 20)
  println(map3("张三"))
  map3.update("张三", 29)

4.9.3. 遍历map

复制代码
for(elem <- map3)println(elem)
  for((k,v) <-map3)println(k,v)
  map3.foreach(println)

4.9.4. 常见操作

需求:

定义一个可变 Map,包含以下元素: "张三" -> 18 , "李四" -> 19 , "王五" -> 20

获取张三的年龄

获取所有学生姓名

获取所有学生年龄

获取所有学生姓名和年龄

获取赵六的年龄,如果赵六不存在则返回 -1

新增一个学生: "赵六" -> 21

将李四从 Map 中移除

复制代码
 var map4 = mutable.Map("张三" -> 18 ,"李四" -> 19 , "王五" -> 20)
  println(map4.get("张三"))
  println(map4.keys)
  println(map4.values)
  for((k,v)<-map4)println(k,v)
  println(map4.getOrElse("赵六", -1))
  println(map4 += "赵六" -> 21)
  println(map4 -= "李四")
  Some(18)
  Set(王五, 张三, 李四)
  HashMap(20, 18, 19)
  (王五,20)
  (张三,18)
  (李四,19)
  -1
  Map(赵六 -> 21, 王五 -> 20, 张三 -> 18, 李四 -> 19)
  Map(赵六 -> 21, 王五 -> 20, 张三 -> 18)

4.10. range

复制代码
  val range01: Range.Inclusive = 1 to 5
  for (i <- range01) println(i)  1 2 3 4 5

  val range03: Range = 1 to 5 by 2
   val range03: Range = Range(1, 5, 2)
   for (i <- range03) println(i)  1 3 5

4.11. 函数式编程

复制代码
遍历foreach
def foreach(f:(A) => Unit): Unit
   简写形式
def foreach(函数)

4.11.1. 去重distinct

复制代码
val list = List(1, 2, 2, 3, 4, 5, 6)
println(list.distinct)  List(1, 2, 3, 4, 5, 6)

4.11.2. 映射map

复制代码
 def map[B](f: (A) => B): TraversableOnce[B]
  // 简写形式
  def map(函数对象)
  val result2 = list.map(x => x * 2)
  println(result2)

4.11.3. 扁平化flatmap

扁平化映射可以理解为先 map,然后再 flatten,它也是将来使用最多的操作,也是必须要掌握的。

def flatMap[B](f: (A) => GenTraversableOnce[B]): TraversableOnce[B]

简写形式

def flatMap(f: (A) => 待转换的集合的处理代码)

复制代码
val list = List("hello world", "a new line", "the end")
  val result3 = list.flatMap(s => s.split("\\s+"))
  println(s"result3 = ${result3}")
 // 根据空格拆分再合并

4.11.4. 过滤filter

复制代码
def filter(f: (A) => Boolean): TraversableOnce[A]
  val result1 = list.filter(x => x % 2 == 0)

4.11.5. 排序

sorted :按默认规则(升序)排序集合

sortBy :按指定属性排序集合

sortWith :按自定义规则排序集合

复制代码
val sortby1 = List("01 zookeeper", "02 hadoop", "03 hive", "04 spark")
  val resSort = sortby1.sortBy(x=>x.split("\\s+")(1))
  val sortWith1 = List("01 zookeeper", "02 hadoop", "03 hive", "04 spark")
  val resSort1 = sortWith1.sortWith((x, y) => x > y)
  println(resSort1)//根据字典序排序从左至右
  List(04 spark, 03 hive, 02 hadoop, 01 zookeeper)

4.11.6. 分组groupBy

复制代码
  val groupList1 = List("张三" -> "男", "李四" -> "女", "王五" -> "男")
  val resGroupBy1 = groupList1.groupBy(x=>x._2)
  println(resGroupBy1)返回Map集合
  Map(男 -> List((张三,男), (王五,男)), 女 -> List((李四,女)))

4.11.7. 聚合reduce

复制代码
def reduce[A1 >: A](op: (A1, A1) => A1): A1
   简写形式
  def reduce(op:(A1, A1) => A1)
  val listRedu = (1 to 10).toList
   使用 reduce 计算所有元素的和
  val resRedu = listRedu.reduce((x, y) => x + y)
  println(resRedu)

  //55
  println(listRedu.reduceLeft(_ - _))
  //-53
  println(listRedu.reduceRight(_ + _))
  //55

4.11.8. 折叠

def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1

简写形式

def fold(初始值)(op:(A1, A1) => A1)

复制代码
val listFold = (1 to 10).toList
  val resFold = listFold.fold(10)((x, y) => x + y)//10为起始值
  println(resFold)
  //65
  println(list.foldLeft(10)(_ - _))
  println(list.foldRight(10)(_ - _))