文章目录

  • 基础篇
    • 函数和方法的关系
    • 声明方式
    • 参数个数
  • 噩梦篇
    • 至简原则
  • 地狱篇(重要)
    • 函数可以作为对象赋值给变量
    • 函数可以作为参数传递给其他函数
      • 练习:
      • 小问题
    • 函数作为返回值使用
    • 闭包
      • 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 函数篇笔记(二)相关推荐

  1. Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、

    1:Scala之函数式编程学习笔记: 1:Scala函数式编程学习:1.1:Scala定义一个简单的类,包含field以及方法,创建类的对象,并且调用其方法:class User {private v ...

  2. Python基础函数学习笔记(二)

    一:格式化打印输出: 一个输出时: area = 20.15 print "The area of the circle is %f sq cm."%area 两个输出时: rab ...

  3. SQL Server Window Function 窗体函数读书笔记二 - A Detailed Look at Window Functions

    这一章主要是介绍 窗体中的 Aggregate 函数, Rank 函数, Distribution 函数以及 Offset 函数. Window Aggregate 函数 Window Aggrega ...

  4. 入门篇笔记二(字迹潦草也请莫见怪)

  5. pythonsze_python学习笔记二 数据类型(基础篇)

    Python基础 对于Python,一切事物都是对象,对象基于类创建 不同类型的类可以创造出字符串,数字,列表这样的对象,比如"koka".24.['北京', '上海', '深圳' ...

  6. ES6学习笔记二arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  7. 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 ...

  8. Spark基础学习笔记13:Scala函数

    文章目录 零.本讲学习目标 一.声明函数 (一)显式声明函数 1.声明格式 2.注意事项 3.案例演示 (1)加法函数 (2)阶乘函数 (二)隐式声明函数 1.声明格式 2.注意事项 3.案例演示 ( ...

  9. python3进阶篇(二)——深析函数装饰器

    python3进阶篇(二)--深析函数装饰器 前言: 阅读这篇文章我能学到什么?   装饰器可以算python3中一个较难理解的概念了,这篇文章由浅入深带你理解函数装饰器,请阅读它. --如果您觉得这 ...

最新文章

  1. 自动识别口罩佩戴模型在线教学,抗疫在家涨知识!
  2. Objective-C Reflection(Objective-C 反射机制)实用随笔笔记(持续更新)
  3. 云网融合 — 电信网络云
  4. node-mongo-服务器封装
  5. ASP.NET跨平台实践:无需安装Mono的Jexus“独立版”
  6. 强行终止python_中国的真实离婚率:一点也不高,反而低的惊人 | 用python计算离婚率...
  7. 通过url判断当前页,动态给导航加样式
  8. 28、深入浅出MFC学习笔记,View功能的加强和重绘效率的提高
  9. linux php错误日志在哪里,宝塔的php错误日志在哪
  10. [转载] Python基础——Numpy库超详细介绍+实例分析+附代码
  11. 【论文】本周论文推荐(迁移学习、阅读理解、对话系统、图神经网络、对抗生成网络等)...
  12. Python Poetry管理包安装速度慢的解决办法
  13. 《刻意练习》学习总结
  14. 中国手机摄像头产业链
  15. 文本预处理:词袋模型(bag of words,BOW)、TF-IDF
  16. java京东秒杀_小猿圈Python之实现京东秒杀功能技巧
  17. CTF题库-实验吧(密码学)之综合篇
  18. php直接读取csv文件,php怎么读取csv文件?
  19. 2022-2028年全球与中国蛋白质补充剂行业市场需求预测分析
  20. 新年优惠不断档,邀请好友还能获得腾讯视频会员及Q币!

热门文章

  1. OPPO R11s首销火爆 时尚设计新潮流获年轻人追捧
  2. 【IDEA checkout分支冲突,点rollback后,之前add但未commit的代码找回】
  3. Android 将asserts文件夹内文件写入SD卡中
  4. 经典啊!空当接龙-1,-2,11982局解法
  5. 教你制作最近网上很火的,微信带小辫子表情包
  6. [免费专栏] ATTACK安全之检测车机中ADB远程调试控制Android系统攻击
  7. 从实际业务出发,浅显的聊聊如何理解领域驱动设计
  8. A ConvNet for the 2020 一篇总结性的论文
  9. https htttp 区别
  10. java毕业设计人人小说系统mybatis+源码+调试部署+系统+数据库+lw