2021-04-18

*@Scala day02

任何的语法结构都有值
while 结构的值是Unit
赋值语句的值也是Unit

package com.syf.scala1015day01.fun

/**
  * Author Amily
  * Date 2021/4/16
  */
object WhileDemo1 {
  def main(args: Array[String]): Unit = {
    var i:Int =0
    val r:Unit=while (i<10){
      println(i)
      i+=1
      i
    }
    println(r)
  }
}
package com.syf.scala1015day01.fun
/**
  * Author Amily
  * Date 2021/4/16
  */
object For1 {
  def main(args: Array[String]): Unit = {
   /* val a:String="abc"//字符串
    //遍历容器  c只读 不能改
    for(c<-a){
      println(c)}
      */
      //使用for输出1 -100
     /* for(i <- 1.to(100)){
        println(i)}
        */
    /*for(i <- 1 to 100){
      println(i)}
      */
    //使用for输出1-100的所有奇数
    /*for (i <- 1.to(100, 2)) {//to有两个参数  参数1 :结束的值 参数2:步长
      println(i)
    }
*/
   /* for(i <- 1 to 100 by 2){
      println(i)
    }*/
    //使用for输出100-1
    /*for(i <- 1 to 100 reverse){
      println(i)
    }*/
    /*for(i < -100 to 1 by -1){
      println(i)*/

  }
}
package com.syf.scala1015day01.fun
/**
  * Author Amily
  * Date 2021/4/16
  */
object For2 {
  def main(args: Array[String]): Unit = {
    //输出1-100所有的奇数
    //循环守卫
    /*for(i <- 1 to 100 if i% 2==1){
      println(i)
    }*/
    //0-99
    /*for (i <- 0 until (100)) {//[1,100)
      println(i)
    }*/
    //引入其他变量
    /*for(i <- 1 to 100 if i%2==0;j=i*i){
      println(s"i=$i,j=$j")
    }*/
  }
}
package com.syf.scala1015day01.fun

import scala.io.StdIn
import scala.util.control.Breaks._

/**
  * Author Amily
  * Date 2021/4/16
  */
object For3 {
  def main(args: Array[String]): Unit = {
    //1.从键盘读入一个整数,判断这个数是不是质数
    val n:Int=StdIn.readInt()
    var isPrime:Boolean=true
    /*try {
      for (i <- 2 until n) {
        if (n % i == 0) {
          isPrime = false
          throw new IllegalArgumentException
        }
      }
    }catch {
      case _=>
    }*/
    //结束循环:本质是自己抛异常,再去捕获异常
    //while do...while for 都可以使用
    //其实任何地方都可以使用
    breakable{
      for (i <- 2 until n) {
        if (n % i == 0) {
          isPrime = false
         break
        }
      }
    }

    if(isPrime){
      println(s"$n 是质数")
    }else{
      println(s"$n 不是质数")
    }
  }
}

scala 中的for循环,本质是一种遍历,遍历集合中的每个元素,
当遍历完最后一个元素之后,自动终止!

  1. 如果要使用for,必须先用容器`
package com.syf.scala1015day01.fun
/**
  * Author Amily
  * Date 2021/4/17
  */
object For4 {
  def main(args: Array[String]): Unit = {
    //9*9乘法表
    for(i <- 1 to 9){
      for (j<- 1 to i){
        print(s"$j*$i=${i*j}\t")
      }
      println()
    }
    //所有的代码都在内循环,则可以使用循环的嵌套
    //实际情况使用很少
    for(i <- 1 to 9; j<- 1 to i){
      print(s"$j*$i=${i*j}\t")
      if(i==j) println()
    }
  }
}
/**
  * Author Amily
  * Date 2021/4/17
  */

object For5 {
  def main(args: Array[String]): Unit = {
    //得到一个序列: 1 4 9 16 .....100*100
    //for推导式
    val r:IndexedSeq[Int]=for(i<- 1 to 100) yield {
      i*i
//      i*i*i
    }
    println(r)

    //"abcd"=>"AbBbCc"
    val s:IndexedSeq[String]=for(c <- "abcd")  yield c.toString.toUpperCase+c
    println(s.mkString(""))
    //更加函数式
    println("abcd".map(c=> c.toString.toUpperCase+c).mkString(""))
  }
}

/*
1.函数的返回值类型可以省略,然后Scala会根据最后一行代码,推导出来函数的返回值类型
一般都是省略
有些情况不能推导:
1.如果函数内有return语句,则类型不能推导
2.返回值类型和推导类型不一致的时候,不要推
3.递归调用的时候不要推
2.如果函数名和函数体之间的=省略,那么这个函数用于返回unit(隐式的返回unit)
函数就成了一个过程
3.如果函数指明返回unit,则用于返回unit’
4.调用函数的时候,如果函数的参数的个数是0,则原括号可以省略
5.在声明函数时候,如果不需要参数,则原括号也可以省略,调用时候,就不能再有原括号
6.函数的参数默认都是val,所以,在函数内都不能更改尽数的值!!!
如果想修改参数的值,则应该定义一个新的局部变量,然后去修改局部变量的值!
7.声明函数的时候参数可以带默认值
def add(a:Int,b:Int,c:Int=3):Int=a+b+c
8.在Java和Scala中,默认传递函数参数,是按照位置来的
Scala中一种另外传递参数的方式:命名参数
add(10, c = 100)
*/

package com.syf.scala1015day01.Day02
/**
  * Author Amily
  * Date 2021/4/17
  */
object Fun4 {
  def main(args: Array[String]): Unit = {
   /*println(add(1, 2, 3))
    println(add(10, 20, 3))
    println(add(100, 20, 3))
    println(add(100, 20))*/
    println(add(10, c = 100))

  }
  def add(a:Int,b:Int=3,c:Int):Int=a+b+c
//  def add(a:Int,b:Int,c:Int=3):Int=a+b+c

}

函数和方法到底有哪些微妙的区别:

  1. 方法:
    严格上来说,使用def定义的叫方法,其实不能叫方法
    2.函数也可以直接定义
    //()=>{}
    val f:Int=>Int=(a:Int)=>{a*a}
    3.函数和方法之间有一个桥梁:
    可以通过_把方法转成函数
    如果有环境,这Scala自动完成
    4.函数可以作为值传递,方法不行

高级特性

  1. 函数可以定义在任何位置
    可以在函数内定义函数
    2.可以把函数当成一个值送回给函数的调用者
    函数的调用者就可以在函数的外部去调用这个返回的函数
    3.可以把函数当成一个值传递给另外一个函数
    4.如果一个函数f可以返回一个函数作为返回值,或者可以接受一个(多个)函数作为参数
    那么这个函数f就称为高阶函数!!!
package com.syf.scala1015day02
/**
  * Author Amily
  * Date 2021/4/17
  */
object High1 {
  def main(args: Array[String]): Unit = {
   val f1:()=> Unit=foo()
    f1()
    def f():Unit={
      println("aaaa")
    }
    def foo1(x:()=>Unit):Unit={
      println(x)
      x()
    }
  }
  def foo():()=>Unit={
    def f():Unit={
      println("aaaa")
    }
    f _
//    f()
  }
}
package com.syf.scala1015day02
/**
  * Author Amily
  * Date 2021/4/17
  */
object High2 {
  def main(args: Array[String]): Unit = {
    //这里就是函数了
    val f1:Int=>Unit =foo _//把方法转成了函数
    f1(10)
    foo(10)
    //直接定义函数
        //函数不能声明返回值类型,只能靠推导
    //()=>{}
    val f:Int=>Int=(a:Int)=>{a*a}
    val r:Int=f(20)
    println(r)
  }
  //方法
  def foo(a:Int):Unit=println(a)
}
package com.syf.scala1015day02
/**
  * Author Amily
  * Date 2021/4/18
  */
object High3 {
  def main(args: Array[String]): Unit = {
    //把方法转化成函数,没有环境,需手动完成
    val add1:(Int,Int)=>Int=add _
    //这个时候也是把方法转成了函数,但是是Scala自动完成的
    val add2:(Int,Int)=>Int=add
    println(add1(10, 20))
    println(add2(10, 20))

    val r: Int= foo(add _ )
    println(r)

//    foo1(add1 )
  }
  def add1():Unit=println("add1....")
  def foo1(op:() => Unit):Unit=op()

  def foo(op:(Int,Int)=>Int):Int={
    op(10,20)
  }
  def add(a:Int,b:Int):Int=a+b
}

1.匿名函数:
没有名字的函数,就是匿名函数
用处:
1.作为实参,直接传递给高阶函数
2.直接作为高阶函数的返回值
2.传递:
foo1((a:Int,b:Int)=>{a+b})
3.在传递匿名函数的时候,参数的类型一般可以利用上下文,人Scala去自动推导
4.foo1(+)
要求:1.匿名函数只能有两个参数
2.每个参数只使用了一次
3.第一个下划线表示第一个参数,第二个下划线表示第二个参数

package com.syf.scala1015day02
/**
  * Author Amily
  * Date 2021/4/18
  */
object High4 {
  def main(args: Array[String]): Unit = {
    val a:()=>Unit=()=>println("aaaa")
    foo(a)

    foo(()=>{println("匿名函数")})
    foo1((a:Int,b:Int)=>{a+b})
    foo1(_+_)
  }
  def foo1(add:(Int,Int)=>Int):Unit={
    println(add(10, 20))
    println(add(100, 200))
    println(add(1000, 2000))
  }

写几个非常经典的高阶函数

foreach
遍历集合中的每个元素

  具体遍历到没个元素的时候做什么事情,那是由调用者来确定

filter
过滤,过滤条件可以通过一个返回boolean的函数来实现

map
映射:一进一出

reduce
聚合操作
1 to 100

package com.syf.scala1015day02

/**
  * Author Amily
  * Date 2021/4/18
  *
  * 快捷键
  * 自动格式化:alt+ctrl+l
  * 复制一行代码:ctrl+d
  */
object High5 {
  def main(args: Array[String]): Unit = {
    val arr1: Array[Int] = Array(30, 5, 7, 60, 10, 20)
    foreach(arr1, a => {
      println(a)
    })
    foreach(arr1, println)

//    val arr2:Array[Int]=filter(arr1,x=>x%2==0)
    val arr2:Array[Int]=filter(arr1,_%2==0)
    foreach(arr2,println)

    val arr3:Array[Int]=map(arr1,x =>x*x)
    foreach(arr3,println)

    val result:Int =reduce(arr1,(x,y)=> x+y)
    println(result)

    val r:Int=reduce(arr1,_+_)
    println(r)
  }
  //聚合查找
  //op:(c1,c2)=>r  c1表示上次聚合的结果,c2这次参与聚合的元素
  def reduce(arr:Array[Int],op:(Int,Int)=>Int):Int={
    var sum:Int  = 0
    for (e <- arr) {
      sum = op(sum,e)
    }
    sum

    var lastReduce:Int=arr(0)
    for(i <- 1 until arr.length){
      lastReduce=op(lastReduce,arr(i))
    }
    lastReduce
  }
  //map操作
  def map(arr:Array[Int],op:Int=>Int)={
    for (elem <- arr) yield op(elem)
  }
  //使用给定的条件对数组进行过滤,过滤条件:返回是true留下
  def filter(arr:Array[Int],condition:Int=> Boolean):Array[Int]={
  //通过一个数组得到一个新的数组  for推导
    for (elem <- arr if condition(elem)) yield elem

  }

  //用来遍历数组的高阶函数
  def foreach(arr: Array[Int], op: (Int) => Unit): Unit = {
    for (elem <- arr) {
      op(elem)
    }
  }
}

闭包:

一个函数,如果访问了外部的局部变量,则这个函数和他访问的局部变量称为一个闭包,
闭包会阻止外部局部变量的销毁,可以把局部变量的使用延伸到函数的外部
package com.syf.scala1015day02
/**
  * Author Amily
  * Date 2021/4/18
  */
object Closure {
  def main(args: Array[String]): Unit = {
    val f:Int=>Int=foo()
    val r:Int=f(10)
    println(r)
  }
  def foo()={
        var a:Int=10
    (b:Int)=>a+b
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值