欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

scala高阶函数和List、Set集合

程序员文章站 2022-05-13 23:50:23
...

给函数起名

格式:
val 函数别名 = fun _

object Test1 {
  def main(args: Array[String]): Unit = {
    val n = fun _ //给函数起名
    val result = n(6)
    println(result)
  }
  def fun(a:Int):Int={
    a*2
  }
}  

匿名函数

格式:
(参数名1:数据类型,参数名2:数据类型…)=>{函数体}

val f = (a:Double,b:Double)=>a+b
val result1 = f(3,4)
println(result1)

高阶函数

定义:带函数参数的函数就是高阶函数
例:

	def fun2(name:String,f:(String)=>Unit):Unit={
    	f(name)
  	}

调用此函数:
方式一:

	fun2("zhangsan",(a:String)=>println(a))

方式二:
方式一中使用匿名函数来作为高阶函数的参数,由于定义的变量在=>后面只出现了一次,所以a可以用_代替,同时可以省略=>前面的参数

	fun2("lisi",println(_))

方式三:
方式一和方式二都使用的是匿名函数作为高阶函数的参数,这里也可以使用普通函数作为高阶函数的参数

	//首先定义一个函数只有一个参数,类型为String,无返回值
	def fun3(name:String): Unit ={
    	println(name)
  	}
  	//在main方法中调用高阶函数
  	fun2("lisi",fun3 _)

高阶函数的案例

  1. 遍历数组或集合

    	val arr = Array(3, 5, 7, 9, 0)
    	//遍历数组或集合
        arr.foreach((x: Int) => print(x + "\t"))
        arr.foreach(println(_))
    
  2. map函数,完成数据清洗

    	//val arr1 = arr.map(_*2)
        val arr1 = arr.map((x:Int) => x * 2)
        arr1.foreach(println(_))
    
  3. 实现如下效果

    	/*
        	实现如下效果:
    	    *
    	    * *
    	    * * *
    	    * * * *
    	    * * * * *
    	    * * * * * *
    	    * * * * * * *
    	    * * * * * * * *
    	    * * * * * * * * *
    	    思路:2*“*”=“**”,1 to 9数组进行数据清洗得到以上字符串数组,然后遍历输出
         */
        (1 to 9).map((x:Int)=>"*"*x).forearch(println(_))
        (1 to 9).map("*" * _).foreach(println(_)) 
    
  4. 按照过滤条件,将原集合中不符合条件的数据过滤掉
    获取1 to 9中的偶数

    	(1 to 9).filter((x: Int) => x % 2 == 0).foreach(println(_))
        (1 to 9).filter(_ % 2 == 0).foreach(println(_))
    
  5. 求1~9的和

    val sum = (1 to 9).reduce((x: Int, y: Int) => x + y)
    val sum2 = (1 to 9).reduce(_ + _)
    

    运算方式:

    x y x+y
    1 2 3
    3 3 6
    6 4 10
    10 5 15
    15 6 21
    21 7 28
    28 8 36
    36 9 45

    reduceRight
    从右往左运算

    val sum3 = (1 to 9).reduceRight(_ - _)//5
    
    x y x-y
    8 9 -1
    7 -1 8
    6 8 -2
    5 -2 7
    4 7 -3
    3 -3 6
    2 6 -4
    1 -4 5
  6. //数组排序

(1 to 9).sortWith((x:Int,y:Int)=>x>y).foreach(println(_))
(1 to 9).sortWith(_ > _).foreach(println(_))

高阶函数练习

  1. 编写函数values(fun:(Int)=>Int,low:Int,high:Int),该函数输出一个集合,对应给定区间内给定函数的输入和输出。比如,values(x=>x*x,-5,5)应该产出一个对偶的集合(-5,25),(-4,16),(-3,9),···,(5,25)

    def values(fun:(Int)=>Int,low:Int,high:Int): ArrayBuffer[Tuple2[Int,Int]] ={//ArrayBuffer中的类型为元组类型,元组中有两个数,都是Int类型
        val arrayBuffer = new ArrayBuffer[Tuple2[Int,Int]]()
        (low to high).foreach((x:Int)=>{
          val t = (x,fun(x))
          arrayBuffer.append(t)
        })
        arrayBuffer
      }
      //调用此函数
      val arrayBuffer = values(x=>x*x,-5,5)
      println(arrayBuffer)
    
  2. 如何用reduceleft得到数组中的最大元素

      def getMax(): Int ={
        (1 to 9).reduceLeft(Math.max(_,_))
      }
      def getMax1(): Int ={
        (1 to 9).reduceLeft((x:Int,y:Int)=>if(x > y)x else y)
      }
      //调用此函数
      val max = getMax()
      println(max)
      val max1 = getMax1()
      println(max1)
    
  3. 用to和reduceLeft实现阶乘函数,不得使用循环或递归

    	def JieChen(n:Int): Int ={
        	(1 to n).reduceLeft(_*_)
      	}
      	//调用此函数
      	val jieChen = JieChen(9)
        println(jieChen)
    
  4. 前一个实现需要处理一个特殊情况,即n<1的情况。展示如何用foldLeft来避免这个需要。(在Scaladoc中查找foldLeft的说明。它和reduceLeft很像,只不过所有需要结合在一起的这些值的首值在调用的时候给出。)

      def JieChen1(n:Int): Int ={
        (1 to n).foldLeft(1)(_*_)//初始值为1
      }
      //调用此函数
      val jieChen1 = JieChen1(9)
      println(jieChen1)
    
  5. 编写函数largest(fun:(Int)=>Int,inputs:Seq[Int]),输出在给定输入序列中给定函数的最大值。举例来说,largest(x=>10x-xx,1 to 10)应该返回25。不得使用循环或递归

      def largest(fun:(Int)=>Int,inputs:Seq[Int]): Int ={
        inputs.map(fun(_)).reduceLeft((x:Int,y:Int)=>if( x > y ) x else y)
      }
      //调用此函数
      val largests = largest((x:Int)=>10*x-x*x,1 to 10)
      println(largests)
    
  6. 修改前一个函数,返回最大的输出对应的输入。举例来说,largestAt(fun:(Int)=>Int,inputs:Seq[Int])应该返回5。不得使用循环或递归

      def largest1(fun:(Int)=>Int,inputs:Seq[Int]):Int={
        inputs.reduceLeft((x:Int,y:Int)=>if(fun(x) > fun(y)) x else y)
      }
      //调用此函数
       val largests1 = largest1((x:Int)=>10*x-x*x,1 to 10)
       println(largests1)
    

List和map集合

复习一遍java集合

Collection
List
ArrayList
LinkedList
Set
Hashset
TreeSet
Map
HashMap 效率高,安全性低,因为它线程异步,允许键和值为null
HashTable 效率低,安全性高,因为它线程同步,不允许键和值为null
LinkedHashMap 添加顺序与出来的顺序相同

列表(List)

在scala中列表要么是空表(Nil),要么是一个head+tail,tail又是一个列表

	  val li = List(2,3,4,5,6,7,8)
      println(li.head)//2
      println(li.tail)//List(3, 4, 5, 6, 7)
	
	  val lb = Nil
      println(lb)//List()

	  //判断集合是否为空
      println(li.isEmpty)

增加:
注意: 不管是增加删除,都会产生一个新的列表,因为scala中的List是不可变的集合,不能被更改

	//在列表li的尾部添加另外一个列表B,组成一个新的列表
      val li1 = li.++(List(10,12,13))
      println(li1)//List(2, 3, 4, 5, 6, 7, 10, 12, 13)
      //在列表li的首部添加另外一个列表B,组成一个新的列表
      val li2 = li.++:(List(14,15,16))
      println(li2)//List(14, 15, 16, 2, 3, 4, 5, 6, 7)
      //在列表li的尾部添加一个元素,组成一个新的列表
      val li3 = li.:+(8)
      println(li3)//List(2, 3, 4, 5, 6, 7, 8)
      //在列表li的首部添加一个元素,组成一个新的列表
      val li4 = li.+:(9)
      println(li4)//List(9, 2, 3, 4, 5, 6, 7)

删除

	//删除List的前n个元素(首部开始删除),并组合成一个新的列表
      val li5 = li.drop(2)
      println(li5)//List(4, 5, 6, 7)

      //删除list的后n个元素(尾部开始删除),并组合成一个新的列表
      val li6 = li.dropRight(2)
      println(li6)//List(2, 3, 4, 5)

      //逐个匹配去除符合条件的元素,直到不符合条件,之后的元素不再判断,组成一个新的列表,如果第一个就不符合,一个都不删
      val li7 = li.dropWhile(_ > 5)
      println(li7)//List(2, 3, 4, 5, 6, 7)
      val li8 = li.dropWhile(_ < 5)
      println(li8)//List(5, 6, 7)

其他常见操作

	//根据下标获取元素
	  val s = li(0)
      println(s)//2
      
      //获取列表前5个元素
      val li9 = li.take(5)
      println(li9)

      //获取满足条件的元素,直到不符合条件,之后的元素不再判断,如果第一个就不符合,就获取不到
      val li10 = li.takeWhile(_ > 3)
      println(li10)//List()
      val li11 = li.takeWhile(_ < 3)
      println(li11)//List(2)

      //将集合变为字符串,中间以""隔开
      val str = li.mkString("")
      println(str)//2345678

      //获取满足条件的元素的个数
      val c = li.count(_ % 2 == 0)
      println(c)//4

      //::操作符从给定的头部和尾部创建一个新的列表
      val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
      println(fruit)//List(apples, oranges, pears)

      //求list中的所有元素的和(必须是整形列表,其他类型的会报错)
      val sum = li.sum
      println(sum)

Set集合

Set集合不是重复元素的集合,不保留元素插入的顺序

	  val set1 = Set(1,2,3,2)
      println(set1)
      
      //添加元素
      val set2 = set1+4
      println(set2)
      
      //遍历
      set2.foreach(println(_))
      
      //排序Set
      val set3 = SortedSet(1,2,3,4,6,5)
      println(set3)//TreeSet(1, 2, 3, 4, 5, 6)
      
      //保留插入顺序
      val set4 = mutable.LinkedHashSet(1,2,3,4,6,5)
      println(set4)//Set(1, 2, 3, 4, 6, 5)