Scala(二)

本文深入探讨了Scala函数参数的两种求值策略:Call By Value和Call By Name,以及Lazy值的概念。此外,还介绍了默认参数、代名参数、可变参数、数组、多维数组和元组的使用。通过实例展示了异常处理、自定义函数,并提供了元组访问和遍历的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Scala函数的参数

Scala中,有两种函数参数的求值策略

Call By Value:对函数实参求值,且仅求一次
Call By Name:函数实参每次在函数体内被用到时都会求值

在这里插入图片描述
我们来分析一下,上面两个调用执行的过程:
在这里插入图片描述
一份复杂一点的例子:
在这里插入图片描述

Scala中的函数参数

默认参数
代名参数
可变参数

在这里插入图片描述

		(1)默认参数
			当你没有给参数赋值的时候,就使用默认值
			scala> def fun1(name:String) : String = "Hello " + name
			fun1: (name: String)String

			scala> fun1("Tom")
			res0: String = Hello Tom

			scala> fun1()
			<console>:13: error: not enough arguments for method fun1: (name: String)String.
			Unspecified value parameter name.
				   fun1()
					   ^

			scala> def fun1(name:String="Andy") : String = "Hello " + name
			fun1: (name: String)String

			scala> fun1("Tom")
			res2: String = Hello Tom

			scala> fun1()
			res3: String = Hello Andy
		
		(2)代名参数
			
			当有多个默认参数的时候,通过代名参数可以确定给哪个参数赋值
			
			scala> def fun2(str:String="Good Morning ",name:String=" Tom ",age:Int=20)=str + name + " and the age of " + name + " is" + age
			fun2: (str: String, name: String, age: Int)String

			scala> fun2()
			res4: String = Good Morning  Tom  and the age of  Tom  is20

			scala> fun2(name= " Mary ")
			res5: String = Good Morning  Mary  and the age of  Mary  is20

		
		(3)可变参数
			
			类似于java中的可变参数。即 参数数量不固定。
			
			举例:求多个数字的和:
			def sum(x:Int,y:Int) = x+y
			
			def sum(x:Int,y:Int,z:Int) = x+y+z
			
			def sum(args:Int*) = {
			var result = 0
			for(x <- args) result += x
			result
			}
			
			scala> def sum(args:Int*) = {
				 | var result = 0
				 | for(x <- args) result += x
				 | result
				 | }
			sum: (args: Int*)Int

			scala> sum(1,2,3)
			res6: Int = 6

			scala> sum(2,3)
			res7: Int = 5


			scala> sum(2,3,4,5,6,7)
			res8: Int = 27
Scala的Lazy值(懒值)

当val被申明为lazy时,它的初始化将被推迟,直到我们首次对它取值。
在这里插入图片描述
一个更为复杂一点的例子:读取文件:
在这里插入图片描述

	铺垫:Spark 核心 RDD (数据集合) 。操作数据集合中的数据时,我们使用算子(函数、方法)。
	算子有两种:
	1、Transformation : 延时计算,不会立刻触发计算   T 
	2、Action : 触发计算    A 
	
	RDD.T.T.T.T.A
	
	Transformation 用了 lazy值
	
	定义:如果被lazy修饰了,他的初始化会被延迟,推迟到第一次使用该常量、变量的时候。
	
	scala> val x : Int = 10
	x: Int = 10

	
	scala> val y : Int = x + 1
	y: Int = 11
	定义后会立即触发计算

	scala> lazy val z : Int = x + 1
	z: Int = <lazy>
	初始化会被延迟,没有触发计算。当我们第一次使用z的时候,才会触发计算

	scala> z
	res9: Int = 11
	
	举例:读文件
		
		(1)读一个存在的文件
		
		
		scala> val words = scala.io.Source.fromFile("H:\\tmp_files\\student.txt").mkString
		words: String =
		1       Tom     12
		2       Mary    13
		3       Lily    15

		scala> lazy val words = scala.io.Source.fromFile("H:\\tmp_files\\student.txt").mkString
		words: String = <lazy>

		scala> words
		res10: String =
		1       Tom     12
		2       Mary    13
		3       Lily    15

		(2)读不存在的文件
		scala> val words = scala.io.Source.fromFile("H:\\tmp_files\\studkjslfkdjlskdjfldent.txt").mkString
		java.io.FileNotFoundException: H:\tmp_files\studkjslfkdjlskdjfldent.txt (系统找不到指定的文件。)
		  at java.io.FileInputStream.open0(Native Method)
		  at java.io.FileInputStream.open(FileInputStream.java:195)
		  at java.io.FileInputStream.<init>(FileInputStream.java:138)
		  at scala.io.Source$.fromFile(Source.scala:91)
		  at scala.io.Source$.fromFile(Source.scala:76)
		  at scala.io.Source$.fromFile(Source.scala:54)
		  ... 32 elided

		scala> lazy val words = scala.io.Source.fromFile("H:\\tmp_files\\stude932409230ijdosijf;oisnt.txt").mkString
		words: String = <lazy>

		scala> words
		java.io.FileNotFoundException: H:\tmp_files\stude932409230ijdosijf;oisnt.txt (系统找不到指定的文件。)
		  at java.io.FileInputStream.open0(Native Method)
		  at java.io.FileInputStream.open(FileInputStream.java:195)
		  at java.io.FileInputStream.<init>(FileInputStream.java:138)
		  at scala.io.Source$.fromFile(Source.scala:91)
		  at scala.io.Source$.fromFile(Source.scala:76)
		  at scala.io.Source$.fromFile(Source.scala:54)
		  at .words$lzycompute(<console>:11)
		  at .words(<console>:11)
  ... 32 elided
异常的处理

Scala异常的工作机制和Java或者C++一样。直接使用throw关键字抛出异常。
在这里插入图片描述

mport java.io.FileNotFoundException

/**
 * Exception
 */
object DemoEx {

  def main(args: Array[String]): Unit = {
    //使用 try catch finally 来捕获异常

    try{
      println("--------try catch finally")
      val words = scala.io.Source.fromFile("E:\\test\\abc\\test.txt").mkString

    }catch {
      case ex : FileNotFoundException => {
        println("FileNotFoundException")
      }case ex : IllegalArgumentException => {
        println("IllegalArgumentException")
      }case _: Exception => {
        println("Exception")
      }
    }finally {
      println("This is finaly")
    }
  }
}
自定义函数
		1、求阶乘 递归
		
		scala> def myFactor(x:Int) : Int = {
			 | if (x <= 1)
			 | 1
			 | else
			 | x*myFactor(x-1)
			 | }
		myFactor: (x: Int)Int
		
		注意:没有return语句。函数的最后一句话就是函数的返回值。
		上面例子中,有函数的分支,1 和 x*myFactor(x-1) 都有可能是函数的最后一句话。
		相当于在前面都有return
		
		scala> myFactor(5)
		res11: Int = 120
		
		2、求输入的年份是否是闰年
		普通闰年:能被4整除但不能被100整除的年份为普通闰年(如 2004年就是闰年,1999年不是闰年)
		世纪闰年:能被400整除的为世纪闰年(如 2000年就是世纪闰年 1900年不是世纪闰年)
		
		scala> def isLeapYear(x:Int) = {
			 | if((x%4==0 && x%100 != 0) || x % 400 ==0) true
			 | else false
			 | }
		isLeapYear: (x: Int)Boolean

		scala> isLeapYear(2008)
		res12: Boolean = true

		scala> isLeapYear(2009)
		res13: Boolean = false
数组
	1、数组的类型
		
		(1)定长数组:Array
			scala> val a = new Array[Int](10)
			a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

			scala> val a = new Array[String](10)
			a: Array[String] = Array(null, null, null, null, null, null, null, null, null, null)

			scala> val a = Array("Tom","Andy","Lily")
			a: Array[String] = Array(Tom, Andy, Lily)

			scala> val a = Array("Tom","Andy","Lily",1)
			a: Array[Any] = Array(Tom, Andy, Lily, 1)

			scala> val a : Array[String] = Array("Tom","Andy","Lily",1)
			<console>:11: error: type mismatch;
			 found   : Int(1)
			 required: String
				   val a : Array[String] = Array("Tom","Andy","Lily",1)
		
		(2)变长数组:ArrayBuffer
		
			scala> import scala.collection.mutable._
			import scala.collection.mutable._

			scala> val a = ArrayBuffer[Int]()
			a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
		
			scala> a
			res13: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

			scala> a += 1
			res14: a.type = ArrayBuffer(1)

			scala> a += 2
			res15: a.type = ArrayBuffer(1, 2)

			scala> a += 10
			res16: a.type = ArrayBuffer(1, 2, 10)

			scala> a += (100,200,300)
			res17: a.type = ArrayBuffer(1, 2, 10, 100, 200, 300)
			
			scala> a.
			++             combinations     groupBy              mapResult           reverse           to
			++:            companion        grouped              max                 reverseIterator   toArray
			++=            compose          hasDefiniteSize      maxBy               reverseMap        toBuffer
			++=:           contains         hashCode             min                 runWith           toIndexedSeq
			+:             containsSlice    head                 minBy               sameElements      toIterable
			+=             copyToArray      headOption           mkString            scan              toIterator
			+=:            copyToBuffer     indexOf              nonEmpty            scanLeft          toList
			-              corresponds      indexOfSlice         orElse              scanRight         toMap
			--             count            indexWhere           padTo               segmentLength     toSeq
			--=            diff             indices              par                 seq               toSet
			-=             distinct         init                 partition           size              toStream
			/:             drop             inits                patch               sizeHint          toString
			:+             dropRight        insert               permutations        sizeHintBounded   toTraversable   g
			:\             dropWhile        insertAll            prefixLength        slice             toVector
			<<             endsWith         intersect            prepend             sliding           transform
			WithFilter     equals           isDefinedAt          prependAll          sortBy            transpose
			addString      exists           isEmpty              product             sortWith          trimEnd
			aggregate      filter           isTraversableAgain   readOnly            sorted            trimStart
			andThen        filterNot        iterator             reduce              span              union
			append         find             last                 reduceLeft          splitAt           unzip
			appendAll      flatMap          lastIndexOf          reduceLeftOption    startsWith        unzip3
			apply          flatten          lastIndexOfSlice     reduceOption        stringPrefix      update
			applyOrElse    fold             lastIndexWhere       reduceRight         sum               updated
			canEqual       foldLeft         lastOption           reduceRightOption   tail              view
			clear          foldRight        length               reduceToSize        tails             withFilter
			clone          forall           lengthCompare        remove              take              zip
			collect        foreach          lift                 repr                takeRight         zipAll
			collectFirst   genericBuilder   map                  result              takeWhile         zipWithIndex

		去掉最后两个元素
		scala> a.trimEnd(2)

		scala> a
		res19: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 10, 100)
		
		遍历数组:
		scala> val a = Array("Tom","Andy","Lily")
		a: Array[String] = Array(Tom, Andy, Lily)

		scala> for(s <- a) println(s)
		Tom
		Andy
		Lily

		scala> a.foreach(println)
		Tom
		Andy
		Lily
		
		
		数据常见操作:
		scala> val myarray = Array(1,2,7,8,10,3,6)
		myarray: Array[Int] = Array(1, 2, 7, 8, 10, 3, 6)

		scala> myarray.max
		res22: Int = 10

		scala> myarray.min
		res23: Int = 1

		scala> myarray.sortWith(_>_)
		res24: Array[Int] = Array(10, 8, 7, 6, 3, 2, 1)

		scala> myarray.sortWith(_<_)
		res25: Array[Int] = Array(1, 2, 3, 6, 7, 8, 10)
		
		解释 myarray.sortWith(_>_)
		sortWith(以某种 规则 进行排序)
		完整:myarray.sortWith((a,b) => {if(a>b) true else false})
		(a,b) => {if(a>b) true else false} 是一个函数。匿名函数:没有名字  传入两个参数 a b 返回值 bool。
		(a,b) => {if(a>b) true else false}  简写 _>_
		匿名函数作为sortWith的参数  高级函数(函数式编程)
多维数组

在这里插入图片描述

	    	多维数组
		
		(1)和Java一样,通过数组的数组来实现
			
			定义一个固定长度的二维数组
			scala> val matrix = Array.ofDim[Int](3,4)
			matrix: Array[Array[Int]] = Array(
			Array(0, 0, 0, 0), 
			Array(0, 0, 0, 0), 
			Array(0, 0, 0, 0))
			
		
			scala> matrix(1)(2) = 10

			scala> matrix
			res27: Array[Array[Int]] = Array(
			Array(0, 0, 0, 0), 
			Array(0, 0, 10, 0), 
			Array(0, 0, 0, 0))
			
		(2)定义一个二维数组,其中每个元素是一个一维数组,但是其长度不固定
		
			scala> val triangle = new Array[Array[Int]](10)
			triangle: Array[Array[Int]] = Array(null, null, null, null, null, null, null, null, null, null)

			scala> for( i <- 0 until triangle.length)
				 | triangle(i) = new Array[Int](i+1)

			scala> triangle
			res29: Array[Array[Int]] = Array(
			Array(0), 
			Array(0, 0), 
			Array(0, 0, 0), 
			Array(0, 0, 0, 0),
			Array(0, 0, 0, 0, 0), 
			Array(0, 0, 0, 0, 0, 0), 
			Array(0, 0, 0, 0, 0, 0, 0), 
			Array(0, 0, 0, 0, 0, 0, 0, 0), 
			Array(0, 0, 0, 0, 0, 0, 0, 0, 0), 
			Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
元组(Tuple)

元组是不同类型的值的聚集。
例如:val t = (1, 3.14, “Fred”) // 类型为Tuple3[Int, Double, java.lang.String]
这里:Tuple是类型,3是表示元组中有三个元素。

元组的访问和遍历:

	Scala中的Tuple:是不同类型值的集合
	
	scala> val t1 = Tuple(1,0.32,"Hello")
	<console>:17: error: not found: value Tuple
		   val t1 = Tuple(1,0.32,"Hello")
					^

	scala> val t1 = Tuple3(1,0.32,"Hello")
	t1: (Int, Double, String) = (1,0.32,Hello)

	scala> val t1 = (1,0.32,"Hello")
	t1: (Int, Double, String) = (1,0.32,Hello)

	scala> val t1 = (1,0.32,"Hello",1,2,3,10)
	t1: (Int, Double, String, Int, Int, Int, Int) = (1,0.32,Hello,1,2,3,10)

	scala> t1.
	_1   _3   _5   _7         copy     hashCode       productElement    productPrefix
	_2   _4   _6   canEqual   equals   productArity   productIterator   toString

	scala> t1._1
	res30: Int = 1

	scala> t1._3
	res31: String = Hello
	
	如何遍历Tuple中的元素
	注意:Tuple没有提供foreach函数,我们使用productIterator
	
	遍历Tuple分成两步:
	1、使用productIterator生成迭代器
	2、遍历
	
	scala> t1.productIterator.
	++                corresponds   foldRight            max         reduceLeft          span           toSeq
	/:                count         forall               maxBy       reduceLeftOption    sum            toSet
	:\                drop          foreach              min         reduceOption        take           toStream
	GroupedIterator   dropWhile     grouped              minBy       reduceRight         takeWhile      toString
	addString         duplicate     hasDefiniteSize      mkString    reduceRightOption   to             toTraversable
	aggregate         exists        hasNext              next        sameElements        toArray        toVector
	buffered          filter        indexOf              nonEmpty    scanLeft            toBuffer       withFilter
	collect           filterNot     indexWhere           padTo       scanRight           toIndexedSeq   zip
	collectFirst      find          isEmpty              partition   seq                 toIterable     zipAll
	contains          flatMap       isTraversableAgain   patch       size                toIterator     zipWithIndex
	copyToArray       fold          length               product     slice               toList
	copyToBuffer      foldLeft      map                  reduce      sliding             toMap

	scala> t1.productIterator.foreach(println)
	1
	0.32
	Hello
	1
	2
	3
	10
小案例
    /**
     *判断101-20之间有多少个的素数
     *
     * 程序分析:
     * 判断素数的方法
     * 用一个数分别去除2到sqrt(这个数),如果可以被整除,则表明次数不是素数,反之是素数
     *
     * 程序实现方法:
     * 定义两层循环
     *  第一层 101-200
     *  第二层 2-sqrt(第一层循环的数)
     *
     *  举例:16
     *  2循环到 sqrt(16)= 4
     *
     *
     */

        //循环的嵌套

        println("----------循环嵌套--------")

        var index_inner = 0
        var count = 0 //保存素数的个数

        for (index_outer <- 101 until 200){
          var b = false //标识是否可以被整除

          breakable{
            index_inner = 2
            while (index_inner <= sqrt(index_outer)) {
              if (index_outer % index_inner ==0){
                //是素数
                b = true
                break
              }
              index_inner += 1
            }
        }
          if (!b) count += 1

        }
      println("个数是:" + count)
  }

}
/**
 * 冒泡排序
 */
object DemoSort {
  /**
   *
   * 算法分析:
   * 1、比较相邻元素,如果第一个比第二个大,就交换。
   * 2、对每一个相邻元素做相同工作,从左往右,第一轮遍历完之后,最后的元素会是最大的数。
   * 3、针对所有元素重复以上步骤,除了已经排好的元素。
   *
   * 程序分析:
   * 1、两层循环。
   * 2、外层循环控制比较的次数。
   * 3、内层循环控制到达的位置,也就是比较结束的位置。
   *
   */
  def main(args: Array[String]): Unit = {
    println("---------冒泡排序--------")
    var a = Array(1,5,3,8,7,9,2,4,6,34,65)
    println("--------排序前----------")
    a.foreach(println)

    for (i <- 0 until a.length - 1){
      for (j <- 0 until a.length -1 -i){
        if (a(j) > a(j+1)){
          //交换
          var tmp = a(j)
          a(j) = a(j+1)
          a(j+1) = tmp
        }
      }
    }
    println("--------排序后---------")
    a.foreach(println)


  }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值