Scala的基本语法:集合应用

集合应用

map映射操作

将集合中的每一个元素通过指定功能(函数)映射(转换)成新的结果集合。

相当于def map[泛型](f: (A) ⇒ B): HashSet[泛型]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vhFuWgEt-1575173838451)(…/…/…/MarkdownPictures/scala/1565874704650.png)]

flatmap映射

flat即压扁 将集合中的每个元素的子元素映射到某个函数并返回新的集合。

val names = List("Alice", "Bob", "Nick")
def upper( s : String ) : String = {
    s. toUpperCase
}
//得到list(A,L,I,C,E,B,O,B,N,I,C,K)

filter集合元素的过滤

filter:将符合要求的数据(筛选)放置到新的集合中,filter()里的函数返回值类型必须是布尔值

val names2 = names.filter(startA)  // 如果startA 返回一个true,则加入到新集合中,否则,过滤

fold折叠

fold函数将上一步返回的值作为函数的第一个参数继续传递参与运算,直到list(集合)中的所有元素被遍历。同外部reduce

  1. reduceLeft相当于简化版的foldLeft,fold函数传入的参数也可以是引用类型比如对象

  2. fold,foldLeft,foldRight 使用同reduce相似

    val list = List(1, 2, 3, 4) def minus( num1 : Int, num2 : Int ): Int = { num1 - num2}
    println(list.foldLeft(5)(minus))//等价对化简 List(5,1,2,3,4)等于minus(minus(minus(minus(5,1),2),3),4)) =-5 
    println(list.foldRight(5)(minus)) // minus(1,minus(2,minus(3,minus(4,5)))) = 3 
    
  3. foldLeft和foldRight 缩写方法分别是:/:和:\

reduce化简

化简:将二元函数引用于集合中的函数 相当于折叠的集合内操作

scala推荐的算法是递归,所以reduce都是两两操作

  1. reduceLeft(f) 从左向右化简,接收的函数需要的形式为 op: (B, A) => B): B

    val list = List(1, 20, 30, 4, 5)
    val sum1 = list.reduceLeft(sum1)// 无需输入()
    def sum1(n1: Int, n2: Int): Int =  n1 + n2
    //List(1, 20, 30, 4, 5)相当于sum(sum(sum(sum(1, 20), 30), 4),5)
    
  2. reduceRight(f)跟reduceLeft(f)相反 从右往左

  3. reduce(f)跟reduceLeft(f)一样

  4. reduceByKey

scan扫描

扫描,即对某个集合的所有元素做fold操作,但是会把产生的所有中间结果(包含输入的参数)放置于一个集合(vector)中保存

  1. 用法 类似fold
  2. scanRight 传入的都在最右边
def minus( num1 : Int, num2 : Int ) : Int = { num1 - num2} 
def add( num1 : Int, num2 : Int ) : Int = {num1 + num2}
val i8 = (1 to 5).scanLeft(5)(minus) //5(1,2,3,4,5) 等价(5, 4, 2,-1,-5,-10)
vector(5, 4, 2,-1,-5,-10)
val i9 = (1 to 5).scanRight(5)(add) 
vector(20,19,17,14,10,5) 

练习题

课堂练习2
val sentence = “AAAAAAAAAABBBBBBBBCCCCCDDDDDDD”
使用映射集合,统计一句话中,各个字母出现的次数
提示:Map[Char, Int]()
使用scala的flodLeft折叠方式实现

 def main(args: Array[String]): Unit = {
    val sentence = "AAAAAABBCCDDDDDD"
    var map1 = Map[Char, Int]()
    val map2 = sentence.foldLeft(map1)(charCount)
    println("map2=" + map2)
    println("map1=" + map1)

    //使用charCount2,生产
    var map3 = mutable.Map[Char, Int]()
    sentence.foldLeft(map3)(charCount2)

    println("map3=" + map3)
  }

  //说明
  //1. map : Map[Char, Int] : 左折叠时传入的第一个参数,返回的类型也是Map[Char, Int]
  //2. c : Char, 因为从 "AAAABCC..." 每次取出的元素就是 Char
  //3. map + (k -> v) // 如果k 没有就是增加,如果存在,是修改
  //4. map.getOrElse(c, 0) + 1 => 统计当前 c 出现的次数
  def charCount( map : Map[Char, Int], c : Char ): Map[Char, Int] = {
    map + (c -> (map.getOrElse(c, 0) + 1)) //不可变map
  }
  //使用可变的Map 玩一把
  def charCount2(map : mutable.Map[Char, Int], c : Char ): mutable.Map[Char, Int] = {
    map += (c -> (map.getOrElse(c, 0) + 1)) //不可变map
  }

扩展

拉链

将两个集合进行 对偶元组合并

val list1 = List(1, 2 ,3)
val list2 = List(4, 5, 6)
println(list1.zip(list2)) //List((1,4), (2,5), (3,6))
  1. 拉链的本质就是两个集合的合并操作,合并后每个元素是一个 对偶元组
  2. 如果两个集合个数不对应,会造成数据丢失。
  3. 集合不限于List, 也可以是其它集合比如 Array
  4. 如果要取出合并后的各个对偶元组的数据,可以按元组方法遍历
for(item<-list3){ print(item._1 + " " + item._2) //取出时,按照元组的方式取出即可  }

迭代器

通过iterator方法从集合获得一个迭代器,通过while循环和for表达式对集合进行遍历

val iterator = List(1, 2, 3, 4, 5).iterator // 得到迭代器
    println("--------遍历方式1 -----------------")
    while (iterator.hasNext) {
        println(iterator.next())
    }
    println("--------遍历方式2 for -----------------")
val iterator2 = List(11, 22, 33, 44, 55).iterator // 得到迭代器
    for(enum <- iterator2) {
      println(enum) //
    }
  1. iterator 的构建实际是 AbstractIterator 的一个匿名子类,该子类提供了
    def iterator: Iterator[A] = new AbstractIterator[A] {
    var these = self
    def hasNext: Boolean = !these.isEmpty
    def next(): A = 
  1. 该AbstractIterator 子类提供了 hasNext next 等方法.
  2. 如果需要重新迭代,重新获取迭代器
  3. 可以使用 while的方式,使用hasNext next 方法变量
原文地址:https://www.cnblogs.com/successok/p/14737324.html