Scala—— 20.系统高价函数

1.带参数的高阶函数

package com.blueicex.learn.highlevelfunctionlearn

/**
 * @author Administrator blueicex
 * @date 2020/2/16 20:18
 * @projectname HighLevelFunction
 * @Mem learn
 */
object HighLevelFunction {
  def main(args: Array[String]): Unit = {

    //使用高阶函数
    val res = test(sum2 _, 3.5)
    println("res=" + res)

    //在scala中,可以把一个函数直接赋给一个变量,但是不执行函数
    val f1 = myPrint _

    f1() //执行
  
    //var f1 = myPrint

    //f1 

  }

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

  //说明
  //1. test就是一个高阶函数
  //2. f: Double => Double 表示一个函数, 该函数可以接受一个Double,返回Double
  //3. n1: Double 普通参数
  //4. f(n1) 在test函数中,执行 你传入的函数
  def test(f: Double => Double, n1: Double) = {
    f(n1)
  }

  //普通的函数, 可以接受一个Double,返回Double
  def sum2(d: Double): Double = {
    println("sum2被调用")
    d + d
  }
  }

2.不带参数的高阶函数

object boke_demo01 {
 
  def main(args: Array[String]): Unit = {
     test2(sayOK)
   }
 
  //说明test2是一个高阶函数,可以接受一个没有输入,返回为Unit的函数
  def test2(f: () => Unit) = {
    f()
  } 
  def sayOK() = {
    println("sayOKKK...")
  }
  
}

3. 集合map

//请将 List(3,5,8) 中的所有元素都 * 2 , 将其结果放到一个新的集合中返回,即返回一个新的 List(6,10,16), 请编写程序实现.
 
  val list = List(3, 5, 8)
  //说明 list.map(multiple) 做了什么
  //1. 将 list 这个集合的元素 依次遍历
  //2. 将各个元素传递给 multiple 函数 => 新 Int
  //3. 将得到新 Int ,放入到一个新的集合并返回
  //4. 因此 multiple 函数调用 3
 
  val list2 = list.map(multiple)
  println("list2=" + list2) //List(6,10,16)
 
  def multiple(n: Int): Int = {
    println("multiple 被调用~~")
    2 * n
  }

4. 集合flatmap

    val names = List("Alice", "Tom", "Nick")
 
    //需求是将List集合中的所有元素,进行扁平化操作,即把所有元素打散
    val names2 = names.flatMap(upper)
    println("names2=" + names2)
 
  }
 
  def upper(s: String): String = {
    s.toUpperCase
  }

5. 集合filter

val names = List("Alice", "Tom", "Nick")
    val names2 = names.filter(startA)
    println("names=" + names)
    println("names2=" + names2)
  }
 
  def startA(str: String): Boolean = {
    str.startsWith("A")
  }

6.reduceLeft

    val list = List(1, 20, 30, 4, 5)
    val res = list.reduceLeft(sum) //接收一个函数时,也可以直接传入一个匿名函数
  
    //执行的流程分析
    //步骤 1 (1 + 20)
    //步骤 2 (1 + 20) + 30
    //步骤 3 ((1 + 20) + 30) + 4
    //步骤 4 (((1 + 20) + 30) + 4) + 5 = 60
 
    println("res=" + res) // 60
    def sum(n1: Int, n2: Int): Int = {
      println("sum被调用~~")
      n1 + n2
    }

7.fold系列

    val list = List(1, 2, 3, 4)
 
    def minus(num1: Int, num2: Int): Int = {
      num1 - num2
    }
 
    //说明
    //1. 折叠的理解和化简的运行机制几乎一样.
    //理解 list.foldLeft(5)(minus) 理解成 list(5,1, 2, 3, 4) list.reduceLeft(minus)
 
    //步骤  (5-1)
    //步骤  ((5-1) - 2)
    //步骤  (((5-1) - 2) - 3)
    //步骤  ((((5-1) - 2) - 3)) - 4 = - 5
 
    println(list.foldLeft(5)(minus)) // 函数的柯里化
 
    理解 list.foldRight(5)(minus) 理解成 list(1, 2, 3, 4, 5) list.reduceRight(minus)
    // 步骤 (4 - 5)
    // 步骤 (3- (4 - 5))
    // 步骤 (2 -(3- (4 - 5)))
    // 步骤 1- (2 -(3- (4 - 5))) = 3
    println(list.foldRight(5)(minus)) //
 

foldLeft和foldRight缩写方法分别是:/:和:\

   
    val list4 = List(1, 9)
    def minus(num1: Int, num2: Int): Int = {
      num1 - num2
    }
    var i6 = (1 /: list4) (minus) // =等价=> list4.foldLeft(1)(minus)
    println("i6=" + i6)
 
    i6 = (100 /: list4) (minus) //=等价=> list4.foldLeft(100)(minus)
    println(i6) // 输出?
 
    i6 = (list4 :\ 10) (minus) // list4.foldRight(10)(minus)
    println(i6) // 输出? 2

7.scanLeft/Right

   def minus( num1 : Int, num2 : Int ) : Int = {
      num1 - num2
    }
 
    //5 (1,2,3,4,5) =>(5, 4, 2, -1, -5, -10) //Vector(5, 4, 2, -1, -5, -10)
    val i8 = (1 to 5).scanLeft(5)(minus) //IndexedSeq[Int]
    println("i8=" + i8)
 
    //普通函数
    def add( num1 : Int, num2 : Int ) : Int = {
      num1 + num2
    }
    //(1,2,3,4,5) 5 => (20,19,17,14, 10,5)
    val i9 = (1 to 5).scanRight(5)(add) //IndexedSeq[Int]
    println("i9=" + i9)

8.zip

偶元组合并

   val list1 = List(1, 2, 3)
    val list2 = List(4, 5, 6)
    val list3 = list1.zip(list2) // (1,4),(2,5),(3,6)
    println("list3=" + list3)

拉链的本质就是两个集合的合并操作,合并后每个元素是一个 对偶元组

9.迭代器

val iterator = List(1, 2, 3, 4, 5).iterator // 得到迭代器
/*
这里我们看看iterator 的继承关系
 def iterator: Iterator[A] = new AbstractIterator[A] {
var these = self
def hasNext: Boolean = !these.isEmpty
def next(): A =
  if (hasNext) {
    val result = these.head; these = these.tail; result
  } else Iterator.empty.next()
 */
println("--------遍历方式1 while -----------------")
while (iterator.hasNext) {
  println(iterator.next())
}
println("--------遍历方式2 for -----------------")
for (enum <- iterator) {
  println(enum) //
}

10.流Stream

stream是一个集合。这个集合,可以用于存放无穷多个元素,但是这无穷个元素并不会一次性生产出来,而是需要用到多大的区间,就会动态的生产,末尾元素遵循lazy规则(即:要使用结果才进行计算)

scala> def numsForm(n: BigInt) : Stream[BigInt] = n #:: numsForm(n + 1)
                                 ^
       warning: type Stream in package scala is deprecated (since 2.13.0): Use LazyList instead of Stream
                                                                ^
       warning: object Stream in package immutable is deprecated (since 2.13.0): Use LazyList (which is fully lazy) instead of Stream (which has a lazy tail only)
numsForm: (n: BigInt)Stream[BigInt]

scala> val stream1 = numsForm(1)
stream1: Stream[BigInt] = Stream(1, <not computed>)

scala> println(stream1)
Stream(1, <not computed>)

scala> println("head=" + stream1.head) 
head=1 

scala> println(stream1.tail)
Stream(2, <not computed>)

11.视图

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

def multiple(num: Int): Int = {
  num
}
 
//如果这个数,逆序后和原来数相等,就返回true,否则返回false
def eq(i: Int): Boolean = {
  println("eq 被调用..")
  i.toString.equals(i.toString.reverse)
}
 
//说明: 没有使用view,常规方式
val viewSquares1 = (1 to 100).filter(eq)
println(viewSquares1)
 
 
//使用view,来完成这个问题,程序中,对集合进行map,filter,reduce,fold...
//你并不希望立即执行,而是在使用到结果才执行,则可以使用view来进行优化.
val viewSquares2 = (1 to 100).view.filter(eq)
println(viewSquares2)
//遍历
for (item <- viewSquares2) {
  println("item=" + item)
}

12.并行集合

Scala为了充分使用多核CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算,主要用到的算法有:Divide and conquer: 分治算法,Scala通过splitters(分解器),combiners(组合器)等抽象层来实现,主要原理是将计算工作分解很多任务,分发给一些处理器去完成,并将它们处理结果合并返回。Work stealin算法,主要用于任务调度负载均衡(load-balancing),通俗点完成自己的所有任务之后,发现其他人还有活没干完,主动(或被安排)帮他人一起干,这样达到尽早干完的目的。

 (1 to 5).foreach(println(_))
 println()
 ((1 to 19)).foreach(print(_))

 val result1 = (0 to 100).map { case _ => Thread.currentThread.getName }.distinct
 val result2 = (0 to 100).par.map { case _ => Thread.currentThread.getName }.distinct

————Blueicex 2020/2/16 20:17 blueice1980@126.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值