*@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循环,本质是一种遍历,遍历集合中的每个元素,
当遍历完最后一个元素之后,自动终止!
- 如果要使用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
}
函数和方法到底有哪些微妙的区别:
- 方法:
严格上来说,使用def定义的叫方法,其实不能叫方法
2.函数也可以直接定义
//()=>{}
val f:Int=>Int=(a:Int)=>{a*a}
3.函数和方法之间有一个桥梁:
可以通过_把方法转成函数
如果有环境,这Scala自动完成
4.函数可以作为值传递,方法不行
高级特性
- 函数可以定义在任何位置
可以在函数内定义函数
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
}
}