Scala 函数篇笔记(二)
文章目录
- 基础篇
- 函数和方法的关系
- 声明方式
- 参数个数
- 噩梦篇
- 至简原则
- 地狱篇(重要)
- 函数可以作为对象赋值给变量
- 函数可以作为参数传递给其他函数
- 练习:
- 小问题
- 函数作为返回值使用
- 闭包
- Q&A
- 闭包小实例
- 柯里化
- 控制抽象
- 递归
- 惰性函数
- 案例应用
- Socket 与序列化
基础篇
Bean
函数编程=>逻辑 不是那么重要 =>函数名 IN Out 是非常重要的### 基本语法 ```scala
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala01_Function {def main(args: Array[String]): Unit = {// scala函数式编程//函数声明方式// def =》define// def 函数名 (参数列表)[:返回值类型]={函数体}//函数调用// 函数名(参数)test("zhangsan")}//参数声明规则=>参数名:参数类型def test(s: String): Unit = {//逻辑代码println("s=" + s)}}
函数和方法的关系
位置上:
函数在任意位置
方法在类中
使用上:
scala没有重载
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala02_Function {def main(args: Array[String]): Unit = {// scala函数式编程//函数 & 方法 区别//方法的概念来自于Java//函数概念来自于scala//scala也是完全函数式编程语言,所以方法其实就是函数//一般情况下,将类中封装的功能函数称之为方法//其他地方封装的功能就称之为函数了//函数可以声明在任意地方,也可以嵌套声明使用//类中的函数就是方法,符合java的语法规则:重写 & 重载//函数是没有重写和重载的概念def test(): Unit = {println("xxx")}
// def test(s:String): Unit ={ //函数没有重载概念
// println("xxx")
// }test()println("zhangsan");println("zhangsan");println("zhangsan");}def test1(): Unit = {println("test1..")}def test1(s: String): Unit = {println("test1..")}}
声明方式
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala03_Function {def main(args: Array[String]): Unit = {// scala函数式编程// 无参,无返回值def fun1(): Unit = {println("fun1...")}fun1()//无参,有返回值def fun2(): String = {return "zhangsan"}println(fun2())//有参,无返回值def fun3(s: String): Unit = {println("name=" + s)}fun3("zhangsan")//有参,有返回值def fun4(name: String): String = {return "name=" + name}print(fun4("zhangsan"))//多参,无返回值def fun5(name: String, age: Int): Unit = {println(s"""|{"username":"$name","age":$age}|""".stripMargin)}fun5("zhangsan",22)//多参,有返回值def fun6(name: String, age: Int): String ={return s"name=$name,age=$age"}println(fun6("zhangsan",25))}}
参数个数
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala05_Function {def main(args: Array[String]): Unit = {//函数参数的个数// 函数的参数不要无限多,最大个数为22,声明时候可以超过22// 但是将函数作为对象赋值给变量时会报错// val a:Funcdef test(i1: Int,i2: Int,i3: Int,i4: Int,i5: Int,i6: Int,i7: Int,i8: Int,i9: Int,i10: Int,i11: Int,i12: Int,i13: Int,i14: Int,i15: Int,i16: Int,i17: Int,i18: Int,i19: Int,i20: Int,i21: Int,i22: Int): Unit = {}val a = test _println(a)//可变参数,相同类型的参数多次出现,但是不确定个数//java=>String..//scala =>String*def test1(i: Int*): Unit = {println(i)}test1()test1(1)test1(1, 2, 3)//可变参数的顺序:放置在最后def test2(age: String, i: Int*): Unit = {}test2("", 2, 3, 4, 20)//同一个参数列表中只能有一个可变参数// def test3(name:String*,age:Int*): Unit ={//// }//scala中函数的参数使用val声明,无法进行修改//scala提供了参数默认值的语法来解决参数默认值的问题// def regUser(name: String, password: String): Unit = {// var pswd = ""// if (password == null) {// password = "000000"// }// }// regUser("张三", null)//参数默认值(初始):参数声明时进行初始化def regUser(name: String, password: String = "000000"): Unit = {println("password=" + password)}//如果函数存在默认值参数,调用时可以不用传递,不传参数,会使用默认值regUser("zhangsan")//如果调用函数时,提供了参数值那么默认值不起作用,被覆盖了regUser("lisi", "123123")def regUse1r(name: String, password: String = "000000", tel: String): Unit = {println("name="+name+",password=" + password + ",tel=" + tel)}// 函数在传递参数时,是按照从左到右的方式进行匹配的,没有默认值必须传
// regUse1r("vanas","123144")regUse1r("vanas","123144","1234444")
// 带名参数:传递参数时添加参数名,明确指定参数regUse1r("张三",tel = "123124134")}}
噩梦篇
至简原则
在各种场景中自行选择省略什么
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala06_Function_NightMare {def main(args: Array[String]): Unit = {//函数编程 -噩梦版//scala中函数有至简原则:能省则省//这里的能省则省,必须是编译器可以自动推断的场合,才能省def test(name: String): String = {return "name=" + name}//1.当函数需要返回值时,可以将函数体中最后一行执行的代码作为返回结果// 所以可以省略return关键字def test1(name: String): String = {"name=" + name}println(test1("zhangsan"))//2.如果编译器可以推断出函数的返回值类型,那么返回值类型可以省略def test2(name: String) = {//返回值自动推断 Any// "name=" + name// 20val age = 20if (age < 20) {"zhangsan"} else {123}}println(test2("zhangsan"))//3.如果函数体的逻辑只有一行代码,那么大括号可以省略def test3(name: String) = "name=" + nameprintln(test3("lisi"))//4.如果函数没有提供参数,那么调用的时候,小括号可以省略//如果函数没有提供参数,那么声明时,小括号也可以省略,调用时,必须不能使用小括号def test4() = "zhangsan"println(test4())println(test4)//同一访问原则 语法不一样,访问方式保持一致//如果声明没有小括号,则调用不许用小括号def test5 = "zhangsan"val abc = "zhangsan"println(test5)//5.函数如果明确使用Unit声明没有返回值,那么函数体中的return关键字不起作用// 函数体中如果明确使用return关键字,那么返回值类型不能省// 明确函数就是没有返回值,但是Unit又不想声明,可以同时省略等号// 将这种函数的声明方式称之为过程函数,不省略花括号def test6(): Unit = {//Unit和return同时存在return不起作用return "lili"}
// 返回值和等号都省掉 花括号不能省 因为判断不了逻辑def test7() {return "vanas"}println(test7())//6.当只关心代码逻辑,不关心函数名称时,函数名和def关键字可以省略// 将没有名称和def关键字的函数称之为匿名函数//规则:(参数列表)=>{代码逻辑} //只有一行花括号也可以去掉//函数调用:函数(变量)名称(参数列表)// JS=>混淆=>a(),b()//声明匿名函数val a = () => println("no name")//调用a()}
}
地狱篇(重要)
哪都能用
下划线的用法:
1.下划线可以作为标识符使用
2.下划线可以将函数作为整体使用
函数可以作为对象赋值给变量
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala08_Function_Hell {def main(args: Array[String]): Unit = {//函数编程 -地狱版//函数也是对象//1.函数可以作为对象赋值给变量def test1() = {"zhangsan"}def test11(i: Int): Int = {i * 2}//将函数赋值给变量,那么这个变量其实就是函数,可以调用//函数如果没有参数列表,那么调用时可以省略小括号//如果此时希望将函数不执行,而是当成一个整体赋值给变量,那么需要使用下划线
// f1 => ()=>Stringval f1 = test1 _println(f1())//如果不想使用下划线明确将函数作为整体使用,那么也可以直接声明变量的类型作为函数//函数类型:参数列表=>返回值类型//变量:变量类型=变量值//变量:函数类型=函数//变量()val f11: () => String = test1val ff1: (Int) => Int = test11 //一个参数括号可以省略println(ff1(10))//2.函数可以作为参数传递给其他函数//3.函数可以作为函数的返回值返回}}
函数可以作为参数传递给其他函数
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala09_Function_Hell {def main(args: Array[String]): Unit = {//函数编程 -地狱版//函数也是对象//2.函数可以作为参数传递给其他函数//函数名(参数名1:参数类型1,参数名2,参数类型2)//函数名(参数名1:函数类型)def test(name: String): String = {"name=" + name}def fun2(i: Int): Int = {i * 2}def test2(f: (Int) => Int) = {//自动判断返回类型f(10)}//2.1将函数赋值为变量val f = fun2 _ //这个方式更好理解些//val f:Int =>Int =fun2println(test2(f))println(test2(fun2 _))println(test2(fun2))//2.2将函数作为参数使用时,一般不关心函数没得名称的,所以一般使用匿名函数// 匿名函数规则: (参数列表)=>{代码逻辑}val result = test2((i: Int) => { i * i })println(result)//至简原则
// val result = test2((i: Int) => { i * i })//如果逻辑代码只有一行,花括号可以省略
// val result = test2((i: Int) => i * i )//如果匿名函数的参数类型可以推断出来,那么类型可以省略
// val result = test2((i) => i * 2)//如果匿名函数的参数列表只有一个或没有,那么小括号可以省略
// val resul = test2(i => i * 2)//如果匿名函数中的参数在逻辑代码中只使用了一次,那么,参数和=>可以省略//使用下划线代替参数val result2 = test2( _ * 2 )println(result2)// val result3 = test2((i) => i * i )val result3 = test2(i => i * i )//3.函数可以作为函数的返回值返回}}
例子
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala10_Function_Hell {def main(args: Array[String]): Unit = {//函数编程 -地狱版def sum(x: Int, y: Int): Int = {x + y}def calcAnalysis(f: (Int, Int) => Int) = {val boyCnt = 20val girlCnt = 20f(boyCnt,girlCnt)}val f = sum _println(calcAnalysis(f))//简化calcAnalysis( (x:Int,y:Int)=>{ x + y })// 一行 省略花括号 calcAnalysis( (x:Int,y:Int)=> x + y )//可以推断 省略intcalcAnalysis( (x,y)=> x + y )// 参数每个使用了一次,所以省略参数列表 用_代替 类似于占位符calcAnalysis( _ + _ ) println(calcAnalysis(_ + _))}}
练习:
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala11_Function_Test {def main(args: Array[String]): Unit = {//函数编程 -小练习//1.如果想把一个任意的数字A通过转换后得到它的2倍,那么这个转换的函数应该如何声明和使用def transform(num: Int): Int = {num * 2}println(transform(5))//2.如果上一题想将数字A转换为任意数据B(不局限为数字),转换规则自己定义,该如何声明def transform2(num: Int, f: (Int) => Any): Any = {f(num)}val result=transform2(5,(i:Int)=>{ "Number is" + i})println(result)//3.如果函数调用: test(10,20,c)的计算结果由参数c来决定,这个参数c你会如何声明def test(x:Int,y:Int,c:(Int,Int)=>Any)={c(x,y)}
// test(10,20,(x:Int,y:Int)=>{x+y})
// test(10,20,(x:Int,y:Int)=>x+y)
// test(10,20,(x,y)=>x+y)test(10,20,(_+_))/*4.如果设计一个用于过滤的函数,你会如何做?要求:对传递的包含多个单词的字符串参数,根据指定的规则对word进行过滤例子:"hello world scala spark" => 首写字母为s => "scala, spark"*/def filter(s:String,fun:(String)=>Boolean):String={val words = s.split(" ")var result = ""for (word <- words ){if (fun(word)){// result += word+","result += ","+word}}// resultresult.substring(1)}
// filter("hello world scala spark",(word:String)=>{word.startsWith("s")})println(filter("hello world scala spark", _.startsWith("s")))}
}
小问题
函数参数不能改
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala12_Function_QA {def main(args: Array[String]): Unit = {//函数编程 //1.函数参数不能改test("xxxxx")}def test(name: String): Unit = {var name = "zhangsan"name = "lisi"}
}//反编译可以看到2个name 参数
匿名函数后面的代码不执行
//2.匿名函数后面的代码不执行//匿名函数没有只声明不调用的,编译器会认为后续也是匿名函数的一部分 编译时会把xxx和yyy放一起() => {println("xxxx")}println("yyyyy")//yyy执行了val f=() => {println("xxxx")}println("yyyyy")
匿名函数参数不使用的简化问题
// 3.匿名函数参数不使用的简化问题//匿名函数使用下划线的时候可以简化参数列表def test(f:(Int)=>Any)={f(1)}test((x:Int)=>{"Hello"})test((x:Int)=>"Hello")test((x)=>"Hello")test(x=>"Hello")test(_+"Hello")//String =>test=>自动转换//Byte =>Short=>int =>longval a:(Int)=>Any ="abc"
// a(1)
循环反向操作
//4.循环反向操作 一般不会这么做 会有其他方法//start endfor(i<- 5 to 1 by -1){println(i)}
def fun : String={“zhangsan”},val aaa:()=>String=fun报错
//5.def fun : String={"zhangsan"},val aaa:()=>String=fun报错def fun :String={"zhangsan"}val a = fun _//val a:()=>String =fun // eror 不能这么用 相当于=>Stringprintln(a())
函数作为参数不理解
//6.函数作为参数不理解 (考虑作用v域问题)def test1 (i :Int): Int ={i*2}def fun1(i:Int): Unit ={println(test1(i))}
//7.
test(i:Int,f:(Int)=>Int)test(1,"abc")能编译通过
for()循环中的i为什么不声明val或var
//8.for()循环中的i为什么不声明val或varval i =10for(i <- 1 to 5){println(i)}
//9.def test3( a:Int):String={return "xxxx"}
// test3 1 //报错 不知道啥意思
// 1 to 5
// 1 toString
函数作为返回值使用
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala13_Function_Hell {def main(args: Array[String]): Unit = {//函数编程 -地狱版//将函数作为返回值使用//将函数的执行结果返回def test(i: Int): Int = {i * 2}def fun() = {test _}//调用函数val a = fun() //当前fun函数的执行结果为函数,那么a此时就是函数println(a(10))println(fun()(10))//当函数作为返回值使用时,一般会使用嵌套函数def fun1() {def test(i: Int) = {i * 2}test _}println(fun()(10))//如果不想使用下划线返回 返回对象 那么需要显示声明函数的返回值类型def fun2(): Int => Int = {def test2(i: Int): Int = {i * 2}test2}println(fun2()(10))}
}
闭包
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala14_Function_Hell {def main(args: Array[String]): Unit = {//函数编程 -地狱版//java->method->压栈->栈帧->弹栈//test//sum//函数在使用外部变量时,如果外部变量失效时,会将这个变量包含到当前的函数内部//形成闭合的使用效果,改变变量的生命周期//这种操作称之为closer(闭包)//1.scala2.12版本中,反编译后。发现编译器重新声明了内部函数的参数,将使用外部变量作为内部函数的参数使用//2.早期scala版本(2.11),闭包会被编译为匿名函数类,如果使用外部变量,会将外部变量作为类的属性// 早期的scala版本(2.11),即使没有使用外部的变量,也会有闭包的效果,只是没有包含外部变量//3.Spark如何判断闭包:判断类名中是否为匿名函数类 $anonfun//4.匿名函数肯定为闭包,将函数赋值给变量使用也是闭包,嵌套的内部函数在外部使用会有闭包def test(i:Int) ={def sum(j:Int) ={i+j}sum _}println(test(10)(20))// def test2() ={ //
// def sum(j:Int) ={
// j
// }
// sum _
// }}
}
private static final int sum$1(final int j, final int i$1) {return i$1 + j;}private static final Function1 test$1(final int i) {return (j) -> {return sum$1(j, i);};}
Q&A
1.new User()创建的对象存放在哪一块内存中?——堆、堆外内存、栈内存
堆,不行 栈内存
把对象分配到栈内存中
//栈上分配
//逃逸分析(对象能不能逃出作用域范围)
2.如何理解GC?
优点:不需要人工参与
缺点:不能人工参与
堆外内存=>操作系统内存=>1/64 =>1/4=>48G =>4G
JVM Heap +堆外内存
闭包小实例
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala15_Function_Hell {def main(args: Array[String]): Unit = {//函数编程 -地狱版//1.函数使用外部变量//当前场合不叫闭包 a没有改变声明周期val a = 10def test(): Unit = {val b = a + 10}test()//当函数赋值给变量 就有闭包val c =test _c()//匿名函数是闭包def test1(f:(Int)=>Int):Unit={println(f(10))}test1((i:Int)=>{i*2})//嵌套函数在内部使用没有在外部使用(改变作用域) 所以不是闭包def test2() ={def sum() ={println("inner sum...")}sum()}test2() }
}
柯里化
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala16_Function_Hell {def main(args: Array[String]): Unit = {//函数编程 -柯里化def test() ={def fun(): Unit ={println("xxxx")}fun _}test()() //觉得麻烦 改善//使用函数柯里化的方式声明函数//所谓的柯里化,其实就是多个参数列表//好处 :1.简化嵌套函数开发// 2.将复杂的参数逻辑简单化,可以支持更多的语法,理解起来也更容易 def test1()(): Unit ={println("test....")}//调用函数test1()()def test2(i:Int)(j:Int)(f:(Int, Int)=>Int)={f(i,j)}println(test2(1)(2)(_+_))}
}
控制抽象
package com.vanas.bigdata.chapter05import sun.tools.jconsole.Plotterimport scala.util.control.Breaks._/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala17_Function {def main(args: Array[String]): Unit = {//函数编程 -控制抽象 (把代码作为参数作为传递)//捕捉异常//breakable是一个函数//参数列表中如果有多行逻辑,可以采用大括号代替//scala支持将代码逻辑作为参数传递给函数使用//如果函数的参数想要传递代码逻辑,那么类型声明的方式应该为://参数名:=>返回值类型(Unit)//因为参数类型中没有声明小括号,所以调用时,也不能加小括号breakable{for (i<- 1 to 5){//抛出异常if (i==3){break}println(i)}}println("main")def fun ={"zhangsan"}test(fun)
// test{fun}//调用test(print("test..."))}def test(f: =>Unit) ={println(f) //不能加括号}
}
应用于写框架 ,类似于模版
Application:
1.初始化环境:数据库,资源文件,数据文件,核心对象的创建
2.逻辑代码:JDBC,load,readLine,obj.xxx
3.环境的关闭和释放
package com.vanas.summer.framework/*** @author Vanas* @create 2020-05-22 8:18 下午 */
class Application {/*** 启动应用* 1.函数柯里化* 2.控制抽象*/def start(t:String)(op: =>Unit):Unit={//1.初始化println(t+"环境初始化")//2.业务逻辑try{op}catch {case ex: Exception => println("业务执行失败"+ex.getMessage)}//3.环境关闭println(t+"环境关闭")}
}
package com.vanas.bigdata.chapter05import com.vanas.summer.framework.Application/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala18_Function extends Application {def main(args: Array[String]): Unit = {start ("jdbc"){println("执行业务逻辑")}}
}
递归
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala19_Function {def main(args: Array[String]): Unit = {//函数编程 -递归-普通递归//1.方法执行过程中调用自身//2.存在可以跳出递归的逻辑,可能会出现StackOverFlowError(栈溢出)//3.方法调用时,传递的参数之间应该存在规律//4.scala中递归方法需要明确返回值类型,不能省略// 递归 -尾递归//递归的方法不依赖于其他外部的变量//编译器碰见尾递归操作时会自动优化为while循环// 阶乘 5!//一个大于1的阶乘等于这个数乘以它减一的阶乘println(factorial((5)))println(test((5)))//扩大栈内存大小 JVM
// println(test((10000000)))fun()println(test1(5, 1))}def fun(): Unit ={println("xxxxx") //如果在后面就会报错fun() //在最后调用它自身 尾递归}/*** 阶乘* @param num* @return*/def factorial(num: Int): Int = {if (num < 1) {1} else {num * factorial(num - 1)}}def test(num: Int): Int = {if (num < 1) {1} else {num + test(num - 1)//test(num - 1) //这种尾递归:在逻辑的最后 但是没有相加}}//5,5+1//4,4+5+1//3,3+4+5+1//2,2+3+4+5+1//1,1+2+3+4+5+1def test1(num: Int,result:Int): Int = {if (num < 1) {result} else {test1(num-1,num+result)}}
}
尾递归长时间处理大量数据同样会出现问题
@tailrec 加标记 作为识别尾递归
惰性函数
package com.vanas.bigdata.chapter05/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala20_Function {def main(args: Array[String]): Unit = {//函数编程 -惰性(lazzy)函数 -延迟加载//lazy延迟加载功能是编译器在编译时产生大量的方法进行调用所实现的//用到数据的时候加载数据//10000 User 暂时没用上 却把内存占上了 长时间占用可能会出现问题 所以希望它 在用到的时候再占用def test() = {println("Xxxxxxxx")"zhangsan"}lazy val name = test()println("************") //1hourprintln("name=" + name)}
}
java中没有函数 类对象方法
案例应用
Scala函数类对象
//将一个对象转换为另外一个类型的对象
思路:Socket+IO+序列化+函数+Any=>函数
Application
package com.vanas.summer.framework.utilimport java.net.{ServerSocket, Socket}/*** @author Vanas* @create 2020-05-22 8:18 下午*/
class Application {var envData: Any = null //为了得到环境变量/*** 开发原则:OCP开发原则 OpenClose(开闭原则)* Open:开发的程序代码应该对功能拓展开放* Close:在扩展的同时不应该对原有的代码进行修改** 启动应用* 1.函数柯里化* 2.控制抽象** t:参数类型:jdbc 、file、hive、kafka,soket,serverSocket*/def start(t: String)(op: => Unit): Unit = {//1.初始化if (t == "socket") {envData = new Socket(PropertiesUtil.getValue("server.host"),PropertiesUtil.getValue("server.port").toInt)} else if (t == "serverSocket") {envData = new ServerSocket(PropertiesUtil.getValue("server.port").toInt)}//2.业务逻辑try {op} catch {case ex: Exception => println("业务执行失败" + ex.getMessage)}//3.环境关闭if (t == "socket") {val socket = envData.asInstanceOf[Socket]if (socket.isClosed) {socket.close()}} else if (t == "serverSocket") {val server = envData.asInstanceOf[ServerSocket]if (server.isClosed) {server.close()}}}
}
配置文件summer.properties
server.port=9999
server.host=localhost
读取配置文件
package com.vanas.summer.framework.utilimport java.util.ResourceBundle/*** @author Vanas* @create 2020-05-23 9:31 上午 */
object PropertiesUtil {//绑定配置文件//ResourceBundle:专门用于读取配置文件,所以读取时,不需要增加扩展名//国际化:I18Nval summer: ResourceBundle = ResourceBundle.getBundle("summer")def getValue(key: String): String = {summer.getString(key)}
}
Task
package com.vanas.summer.framework.bean/*** @author Vanas* @create 2020-05-23 9:54 上午 */
class Task extends Serializable {var data: Int = 0var logic: Int => Int = nulldef compute() = {logic(data)}
}
Server
package com.vanas.bigdata.chapter05import java.io.{ObjectInputStream, ObjectOutputStream}
import java.net.ServerSocketimport com.vanas.summer.framework.bean.Task
import com.vanas.summer.framework.util.Application/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala21_Function_Server extends Application {def main(args: Array[String]): Unit = {start("serverSocket") {val server = envData.asInstanceOf[ServerSocket]while (true) {var client = server.accept()new Thread(new Runnable {override def run(): Unit = {//inval inObject = new ObjectInputStream(client.getInputStream)val task = inObject.readObject().asInstanceOf[Task]//inObject.close()//关闭socket的输入流,但同时输出流可用client.shutdownInput()//outval outObject = new ObjectOutputStream(client.getOutputStream)val result = task.compute()//Out ->function ->对象outObject.writeObject(result)outObject.close()if (!client.isClosed) {client.close()}client = null}}).start()}}}
}
Client
package com.vanas.bigdata.chapter05import java.io.{ObjectInputStream, ObjectOutputStream}
import java.net.Socketimport com.vanas.summer.framework.bean.Task
import com.vanas.summer.framework.util.Application/*** @author Vanas* @create 2020-05-20 11:09 上午 */
object Scala22_Function_Client extends Application {def main(args: Array[String]): Unit = {start("socket") {val client = envData.asInstanceOf[Socket]val outObject = new ObjectOutputStream(client.getOutputStream)//Out ->function ->对象//scala中的类默认都是已经序列化的//函数对象val task = new Task()task.data = 10task.logic = _ * 2// val fun = (x: Int) => {
// x * 2
// }outObject.writeObject(task)outObject.flush()//关闭socket输出流,但是输入流可用client.shutdownOutput()//Inval inObject = new ObjectInputStream(client.getInputStream)val result = inObject.readObject().asInstanceOf[Int]println("结果:" + result)
// client.shutdownInput()inObject.close()}}
}
Socket 与序列化
Scala 函数篇笔记(二)相关推荐
- Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、
1:Scala之函数式编程学习笔记: 1:Scala函数式编程学习:1.1:Scala定义一个简单的类,包含field以及方法,创建类的对象,并且调用其方法:class User {private v ...
- Python基础函数学习笔记(二)
一:格式化打印输出: 一个输出时: area = 20.15 print "The area of the circle is %f sq cm."%area 两个输出时: rab ...
- SQL Server Window Function 窗体函数读书笔记二 - A Detailed Look at Window Functions
这一章主要是介绍 窗体中的 Aggregate 函数, Rank 函数, Distribution 函数以及 Offset 函数. Window Aggregate 函数 Window Aggrega ...
- 入门篇笔记二(字迹潦草也请莫见怪)
- pythonsze_python学习笔记二 数据类型(基础篇)
Python基础 对于Python,一切事物都是对象,对象基于类创建 不同类型的类可以创造出字符串,数字,列表这样的对象,比如"koka".24.['北京', '上海', '深圳' ...
- ES6学习笔记二arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
- main 函数解析(二)—— Linux-0.11 学习笔记(六)
main函数解析(二)--Linux-0.11 学习笔记(六) 4.6 blk_dev_init函数 void blk_dev_init(void) {int i;for (i=0 ; i<NR ...
- Spark基础学习笔记13:Scala函数
文章目录 零.本讲学习目标 一.声明函数 (一)显式声明函数 1.声明格式 2.注意事项 3.案例演示 (1)加法函数 (2)阶乘函数 (二)隐式声明函数 1.声明格式 2.注意事项 3.案例演示 ( ...
- python3进阶篇(二)——深析函数装饰器
python3进阶篇(二)--深析函数装饰器 前言: 阅读这篇文章我能学到什么? 装饰器可以算python3中一个较难理解的概念了,这篇文章由浅入深带你理解函数装饰器,请阅读它. --如果您觉得这 ...
最新文章
- 自动识别口罩佩戴模型在线教学,抗疫在家涨知识!
- Objective-C Reflection(Objective-C 反射机制)实用随笔笔记(持续更新)
- 云网融合 — 电信网络云
- node-mongo-服务器封装
- ASP.NET跨平台实践:无需安装Mono的Jexus“独立版”
- 强行终止python_中国的真实离婚率:一点也不高,反而低的惊人 | 用python计算离婚率...
- 通过url判断当前页,动态给导航加样式
- 28、深入浅出MFC学习笔记,View功能的加强和重绘效率的提高
- linux php错误日志在哪里,宝塔的php错误日志在哪
- [转载] Python基础——Numpy库超详细介绍+实例分析+附代码
- 【论文】本周论文推荐(迁移学习、阅读理解、对话系统、图神经网络、对抗生成网络等)...
- Python Poetry管理包安装速度慢的解决办法
- 《刻意练习》学习总结
- 中国手机摄像头产业链
- 文本预处理:词袋模型(bag of words,BOW)、TF-IDF
- java京东秒杀_小猿圈Python之实现京东秒杀功能技巧
- CTF题库-实验吧(密码学)之综合篇
- php直接读取csv文件,php怎么读取csv文件?
- 2022-2028年全球与中国蛋白质补充剂行业市场需求预测分析
- 新年优惠不断档,邀请好友还能获得腾讯视频会员及Q币!
热门文章
- OPPO R11s首销火爆 时尚设计新潮流获年轻人追捧
- 【IDEA checkout分支冲突,点rollback后,之前add但未commit的代码找回】
- Android 将asserts文件夹内文件写入SD卡中
- 经典啊!空当接龙-1,-2,11982局解法
- 教你制作最近网上很火的,微信带小辫子表情包
- [免费专栏] ATTACK安全之检测车机中ADB远程调试控制Android系统攻击
- 从实际业务出发,浅显的聊聊如何理解领域驱动设计
- A ConvNet for the 2020 一篇总结性的论文
- https htttp 区别
- java毕业设计人人小说系统mybatis+源码+调试部署+系统+数据库+lw