Scala_数据结构_02_集合操作_map

高阶函数

object HighOrderT1 {
  def main(args: Array[String]): Unit = {
    //在scala中,可以把一个函数直接赋给一个变量,但是不执行函数
    val m1 = myPrint _
    println(m1  )

   //函数直接赋给一个变量,但是不执行函数 addSum _
    val i = Htest(addSum _, 30)
    println(i)

    Htest2(myPrint)
  }

  def myPrint(): Unit = {
    println("hello")}

  def Htest (f: Int=> Int, num: Int) = {
    f(num)}

  def addSum (i: Int) : Int = {
    i * 2}

 //说明Htest2是一个高阶函数,可以接受一个 没有输入,返回为Unit的函数
  def Htest2(f: ()=>Unit): Unit = {
    f()}
}

map映射操作

在Scala中通过map映射解决:集合中的每一个元素通过指定功能(函数)映射(转换)成新集合

将函数作为参数传递给另外一个函数,这是函数式编程的特点

object MapTest1 {
  def main(args: Array[String]): Unit = {
    val list1 = List(10,20,30,40)

    //1. 将list1这个集合的元素 依次遍历 将各个元素传递给 multiple 函数 => 新Int
    //2. 将得到新Int ,放入到一个新的集合并返回 multiple 函数调用4次
    val list2 = list1.map(multiple)
    println(list2)  //List(20, 40, 60, 80)

    //1. 将names这个集合的元素 依次遍历 将各个元素传递给 stringTrans 函数 => 新String
    //2. 将得到新String ,放入到一个新的集合并返回 names_new
    val names = List("Alex", "Bob", "Sully")
    val names_new = names.map(stringTrans)
    println(names_new) //List(ALEX, BOB, SULLY)

  }

  def multiple(n:Int): Int = {
    println("multiple 被调用~~")
    2 * n}

  def stringTrans(s: String) : String ={
    s.toUpperCase()}

}

flatmap:flat即压扁,压平,扁平化,效果就是将集合中的每个元素的子元素映射到某个函数并返回新的集合。
filter:将符合要求的数据(筛选)放置到新的集合中

object MapTest1 {
  def main(args: Array[String]): Unit = {
    val list1 = List(10,20,30,40)

    //1. 将list1这个集合的元素 依次遍历 将各个元素传递给 multiple 函数 => 新Int
    //2. 将得到新Int ,放入到一个新的集合并返回 multiple 函数调用4次
    val list2 = list1.map(multiple)
    println(list2)  //List(20, 40, 60, 80)

    //1. 将names这个集合的元素 依次遍历 将各个元素传递给 stringTrans 函数 => 新String
    //2. 将得到新String ,放入到一个新的集合并返回 names_new
    //  A => B  String => B
    val names = List("Alex", "Bob", "Sully")
    val names_new = names.map(stringTrans)
    println(names_new) //List(ALEX, BOB, SULLY)

   // flatmap 将集合中的每个元素的子元素映射到某个函数并返回新的集合
   // 进行扁平化操作,即把所有元素打散
    // A => IterableOnce[B]   string => IterableOnce[B]
    val names_flat = names.flatMap(stringTrans)

    println(names_flat) //List(A, L, E, X, B, O, B, S, U, L, L, Y)
    // Filter A => Boolean  A 泛型; String => Boolean
    // 数据(筛选)放置到新的集合中
    val names_filter = names.filter(stringeql)
    println(names_filter) //List(Alex)
  }

  def multiple(n:Int): Int = {
    println("multiple 被调用~~")
    2 * n}

  def stringTrans(s: String) : String ={
    s.toUpperCase()}

  def stringeql(s: String) : Boolean ={
    s.startsWith("A")
  }
}

化简 - 二元函数引用于集合中的函数

object ReduceTest1 {
  def main(args: Array[String]): Unit = {

    //简化 求和
    //def reduceLeft[B >: A](op: (B, A) => B): B
    //reduceLeft(f) 接收的函数需要的形式为 op: (B, A) => B): B  理解为 传个函数(俩参数) 返回一个值(给left or right)
    //reduceleft(f) 的运行规则是 从左边开始执行将得到的结果返回给第一个参数 //步骤1 (1 + 2)
    // 再和下一个元素运行,继续返回给第一个参数   //步骤2 (1 + 2) + 3

    val list1 = List(1, 2, 3)
    val result = list1.reduceLeft(addSum)
    println(result)

    val list2 = List(10, 20, 30)
    println(list2.reduceLeft(mins))  // -40 (10-20) -30
    println(list2.reduceRight(mins)) // 20  10- (20-30)

    //最小值
    val list3 = List(100, 20, 30)
    println( list3.reduceLeft(minValue) )  //20
  }

  def addSum(i1: Int, i2: Int) :Int = {
    i1 + i2}

  def mins (j1: Int, j2: Int): Int ={
    j1 - j2}

  def minValue(x1: Int, x2: Int) : Int = {
    if (x1 > x2) x2 else  x1
  }
}

折叠
fold函数将上一步返回的值作为函数的第一个参数继续传递参与运算,直到list中的所有元素被遍历

object FoldTest1 {
  def main(args: Array[String]): Unit = {
    val list1 = List(1, 2, 3, 4)

    // 函数的柯里化
    // 源码:
    //override def foldLeft[B](z: B)(op: (B, A) => B): B = {
    //    var acc = z ; var these: LinearSeq[A] = coll   //定义一个集合
    //    while (!these.isEmpty) {
    //      acc = op(acc, these.head)  //op(acc,集合第一个元素) 返回值-> acc
    //      these = these.tail    }      // 集合 为 these tail (出去head 剩余元素)
    //    acc   // 返回acc
    //  }
    //(20-1) -1  -> ((20-1) -1) -2 ....

    val result1 = list1.foldLeft(20)(mins)  //20
    println(result1)  //10

    val result2 = list1.foldRight(20)(mins)
    println(result2 ) //18   (4-20) -> 3-(4-20) #19-> 2 -19 #-17 -> 1-(-17) 18
    
  }
  def mins(i1: Int, i2: Int) :Int = {
    i1 - i2}
}

扫描,即对某个集合的所有元素做fold操作,但是会把产生的所有中间结果放置于一个集合中保存

object ScanTest {
  def main(args: Array[String]): Unit = {

    //扫描,即对某个集合的所有元素做fold操作,但是会把产生的所有中间结果放置于一个集合中保存
    // (1 to 5) 遍历,先把 5 保留下来 (5, ) 然后再 开始fold(1,2,3,4,5) -> (5, 4, 2, -1, -5, -10)
    val result = (1 to 5).scanLeft(5)(minus) //IndexedSeq[Int]
    println("result=" + result) // 返回一个IndexSeq[] 索引序列

   // (  50) 右flod (1,2,3,4,5) -> ( 1-8 ,2-(-6) ,3-9 ,4-(-5) , -5, 10)
    var result_right = (1 to 5).scanRight(10)(minus)
    println(result_right)  //Vector(-7, 8, -6, 9, -5, 10)

  }

  def minus( num1 : Int, num2 : Int ) : Int = {
    num1 - num2
  }
}

扩展 Others
拉链(对偶元组合并) 本质就是两个集合的合并操作,合并后每个元素是一组 对偶元组
迭代器  iterator方法从集合获得一个迭代器 hasNext  next()

object OthersTest {
  def main(args: Array[String]): Unit = {
    //本质就是两个集合的合并操作,合并后每个元素是一组 对偶元组
    //两个集合个数不对应,会造成数据丢失  不限于List, 也可以是其它集合(Array)

    val list1 = List(1, 2, 3)
    val list2 = List(11, 22, 33)
    val list3 = list1.zip(list2) //List((1,11), (2,22), (3,33))
    println("list3=" + list3)

    //如果要取出合并后的各个对偶元组的数据,可以遍历
    for (item <- list3){
      println(item._1 + " - "+ item._2) //1 - 11
    }

    // 迭代器 通过iterator方法从集合获得一个迭代器
    val iterator = list1.iterator
    while (iterator.hasNext){
      println(iterator.next())
    }
    // 指针要重置下
    val iterator2 = list1.iterator
    for (ee <- iterator2) {
      println(ee)}
  }
}

view方法产出一个总是被懒执行的集合。
view不会缓存数据,每次都要重新计算,比如遍历View

object ViewTest {
  def main(args: Array[String]): Unit = {
    val viewSquares1 = (1 to 50).filter(eq)
    println(viewSquares1)  //Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44)

    //使用view,来完成这个问题,程序中,对集合进行map,filter,reduce,fold...
    //你并不希望立即执行,而是在使用到结果才执行,则可以使用view来进行优化.
    val viewSquares2 = (1 to 30).view.filter(eq)
    println(viewSquares2)  //View(<not computed>) filter并未执行 待真正调用时候执行

    //eq 被调用.. 10 调用 未打印
    //eq 被调用.. 11 调用  打印出来
    //11
    for (item <- viewSquares2){    // 操作viewSquare2 时候 filter才会生效
      println(item)}
  }

  def multiple(num: Int): Int = {
    num}

  def eq(i: Int): Boolean ={
    println("eq 被调用..")
    i.toString.equals(i.toString.reverse)
  }

}
posted @ 2021-05-04 14:44  hzcya911  阅读(5)  评论(0)    收藏  举报