scala与java之间的关系,我认为可以用一句话来开头:scala来源于java,但又高于java。

  scala的设计者Martin Odersky就是一个JAVA控,这位牛人设计了javac和编写了jdk中的通用代码。可以说java语言本身就是Martin Odersky一步一步看着长大的。所以scala可以说打根起就和JAVA有着远远悠长的血缘关系。

  Martin Odersky还在写java那会,就立志开发达成一个目标:让写程序这样一个基础工作变得高效、简单、且令人愉悦!因此可以说scala是这个目标实现过程中的一个重要里程碑。

  因此可以说java是职业装,scala就是休闲服。

  scala简练,高效。java成熟,稳重。

  但是尺有所长,寸有所短。scala的简练高效有其独有的使用范围:scala最适合用在算法描述领域,java适合用在指令编程领域。

scala独有的两招:函数式编程、简单的并发编程.

1、scala独有的函数式编程。

  函数是scala语言中的一等公民。

  一等公民的特权表现在:1.函数可以传递、赋值
             2.scala中有嵌套函数和匿名函数
               3.scala支持高阶函数
             4.scala支持偏应用(偏函数)
             5.scala支持闭包

  举例来说:

  1.可传递
  

 def  func(f:()  =>  String)  =  println(f())
func(() => "hi")
//output: hi def foo() = "ok"
func(foo)
//output: ok val fun = (x:Int) => print(x)
fun(2)
//output:2

  2.嵌套函数

 def foo(){
def bar(){
println("hi")
}
bar //exec
} foo //output:hi

嵌套函数在实际中应用场景不多,其中一个场景是将递归函数转为尾递归方式!

 def fun1(){
.....
this
} def fun2(){
....
this
} //两个函数可以如下方式使用
fun1().fun2()

  3.匿名函数

 lambda:函数字面量(Function literal)
(x:Int,y:Int) => x +y
参数 右箭头 函数体 上面语句产生一段匿名函数,类型为(Int,Int) => Int
注意:scala中函数的参数个数为0到22个

  4.高阶函数

 第一种:用函数做参数的函数。eg:

 def f2(f:() => Unit) {f()}

 def f1(){println(1)}

 f2(f1)

 f2(() => println("hi")) //传入匿名函数

 第二种:产生的结果是一个函数的函数。eg:

 def hf():Int => Int = x => x +1

 val fun = hf

 fun(2) //output:3

  5.函数柯里化

 当函数具有多个参数时
def sum(x:Int,y:Int) = x + y //参数被打散后,两个参数分开
def sum2(x:Int)(y:Int) = x + y sum2(1)(2) //output:3 scala> def first(x:Int)=(y:Int) => x+y
first: (x: Int)Int => Int scala> first(1)
res10: Int => Int = <function1> scala> val second=first(1)
second: Int => Int = <function1> scala> second(2)
res11: Int = 3 函数链
把一个带有多个参数的函数,转换为多个只有一个参数的函数来执行 f(1)(2)(3) 相当于 ((f(1))(2))(3) 带入参数 1执行 fa(1) 然后 带入参数2执行 fb(2) 接着带入参数3执行fc(3) 最后得到结果 柯里化的实际用途?
控制抽象,可改变代码的书写风格 foo(res,()=>println(res)) foo(res)(()=> println(res)) foo(res){()=> println(res)}
实现部分应用函数
scala> def log(time:java.util.Date,msg:String){println(time+msg)}
log: (time: java.util.Date, msg: String)Unit scala> val log2 = log(new java.util.Date,_:String)
log2: String => Unit = <function1> scala> log2("test1")
Mon Sep 09 23:46:15 CST 2013test1 scala> log2("test2")
Mon Sep 09 23:46:19 CST 2013test2 scala> log2("test3")
Mon Sep 09 23:46:22 CST 2013test3

  6.闭包

 在java中匿名内部类访问局部变量是,局部变量必须声明为final(类似闭包的实现)

 scala中没有那么麻烦:

 scala> val more = 1
more: Int = 1 scala> val addMore = (x: Int) => x + more
addMore: Int => Int = <function1> scala> addMore(10)
res19: Int = 11

(以上案例部分参考互联网已公开的案例和<Programming in Scala>中部分说明)

2、scala简单的并发编程模型

  scala的并发编程采用的是actor模型,即参与者模型(国内有个通俗术语叫做观察者模式)。

  简而言之就是每个参与者将自身的状态变化通过某种方式广播出去,其他参与者获取到这种状态变化后,再决定是否继续参与。

  scala使用精炼的函数式编程实现了actor模型,从而可以实现同一JVM单核并发,同一JVM多核并发,多个JVM之间并发,并且还可以实现某种意义上的IPC。

  典型的actor编程模型如下:

  

 Scala写法1:

 import actors.Actor,actors.Actor._

 class A1 extends Actor {

 def act {
react {
case n:Int=>println(perfect(n))
}
}
} n to n+10 foreach (i=>{
(new A1).start ! i
}
)
 val aa = Array.fill(11)(actor {
react {
case n:Int=>println(perfect(n))
}
}
) n to n+10 foreach (i=>aa(i-n) ! i)

  两种写法只是区别在声明类方式上面,一种需要显式调用start,另外一个不需要而已。

  不同JVM之间的通讯模型如下:

  服务端:

  

 import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._
import org.andy.scala.actor.model.ActorDeal class ActorServer extends Actor { def act(){ alive(9999) //绑定端口
register('ActorServer, self) //注册服务类 while(true){
receive {
case str:String =>print("There is say "+str)
case _=>println("There is no message ")
}
} }
}

  客户端:

 import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._
import scala.actors.Actor
import org.andy.scala.actor.model.ActorDeal class ActorClient extends Actor {
def act(){
val actServer = select(Node("127.0.0.1", 9999), 'ActorServer)
//每隔5秒发送一次
while(true){
actServer ! "Hello "
print("===Send Hello== ")
Thread.sleep(5000)
}
}
}

  其中后的效果如下:

客户端
client init success
===Send Hello== ===Send ad==
===Send Hello== ===Send ad==
===Send Hello== ===Send ad==
===Send Hello== ===Send ad==
===Send Hello== ===Send ad==
===Send Hello== ===Send ad==
===Send Hello== ===Send ad==
===Send Hello== ===Send ad==
服务端
server init success
There is say Hello
There is say Hello
There is say Hello
There is say Hello
There is say Hello

  这个模型是最简单的不同JVM之间的通讯,我们再添加一点难度!传递一个对象尝试一下:

  对象定义如下:

 class ActorDeal extends Serializable {

   var msg: String = ""

   def dealPrint() = {
println("From deal " + msg)
}
}

  客户端:

 import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._
import scala.actors.Actor
import org.andy.scala.actor.model.ActorDeal class ActorClient extends Actor {
def act(){
val actServer = select(Node("127.0.0.1", 9999), 'ActorServer)
var ad = new ActorDeal()
ad.msg ="WORLD"
while(true){
actServer ! "Hello "
print("===Send Hello== ")
actServer!ad
println("===Send ad==")
Thread.sleep(5000)
}
}
}

  高亮部分为新增的对象操作

  服务端:

 import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._
import org.andy.scala.actor.model.ActorDeal class ActorServer extends Actor {
RemoteActor.classLoader= getClass().getClassLoader() def act(){ alive(9999)
register('ActorServer, self) while(true){
receive {
case ad:ActorDeal => dealAD(ad)
case str:String =>print("There is say "+str)
case _=>println("There is no message ")
}
} } def dealAD(adm:ActorDeal)={
println("Receive AD")
adm.dealPrint }
}

  标红的语句是最重要的一句,如果没有这句,scala actor将会报ClassNotFound异常。所以一定要添加上去

  好,运行后的结果如下:

 server init success
There is say Hello Receive AD
From deal WORLD
There is say Hello Receive AD
From deal WORLD
There is say Hello Receive AD
From deal WORLD

  既然写到分布式编程了,那么就再添加一点reply的东西。

  下面的代码表示的服务端如何给客户端回复响应,请看代码:

  服务端

  

import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._
import org.andy.scala.actor.model.ActorDeal class ActorServer extends Actor {
RemoteActor.classLoader= getClass().getClassLoader() def act(){ alive(9999)
register('ActorServer, self) while(true){
receive {
case ad:ActorDeal => dealAD(ad)
case str:String =>print("There is say "+str)
case _=>println("There is no message ")
}
} } def dealAD(adm:ActorDeal)={
println("Receive AD")
adm.dealPrint
reply("Yet I receive")
}
}

  高亮部分就服务端的回复语句。既然服务端有回复,那么客户端是不是也要关心一下呢?

  客户端

  

import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._
import scala.actors.Actor
import org.andy.scala.actor.model.ActorDeal class ActorClient extends Actor {
def act(){
val actServer = select(Node("127.0.0.1", 9999), 'ActorServer)
var ad = new ActorDeal()
ad.msg ="WORLD"
while(true){
actServer ! "Hello "
print("===Send Hello== ")
var fu =actServer!!ad
println("===Send ad==")
var result = fu()
println("===Receive=="+result)
Thread.sleep(5000)
}
}
}

  首先客户端调用“!!”就是一个等待响应的阻塞方法,这里只要收到服务端回复的确认字符串即可。

  结果如下:

  

client init success
===Send Hello== ===Send ad==
===Receive==Yet I receive

  如果我们增加点难度,回复一个对象。那又该如何处理呢?请看代码:

  服务端:

import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._
import org.andy.scala.actor.model.ActorDeal class ActorServer extends Actor {
RemoteActor.classLoader= getClass().getClassLoader() def act(){ alive(9999)
register('ActorServer, self) while(true){
receive {
case ad:ActorDeal => dealAD(ad)
case str:String =>print("There is say "+str)
case _=>println("There is no message ")
}
} } def dealAD(adm:ActorDeal)={
println("Receive AD")
adm.dealPrint
adm.msg ="I have achieve target"
reply(adm)
}
}

  我们修改了对象数据,然后reply回去。

  这次客户端会有大动作,请看:

import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._
import scala.actors.Actor
import org.andy.scala.actor.model.ActorDeal class ActorClient extends Actor {
RemoteActor.classLoader = getClass().getClassLoader()
def act(){
val actServer = select(Node("127.0.0.1", 9999), 'ActorServer)
var ad = new ActorDeal()
ad.msg ="WORLD"
while(true){
actServer ! "Hello "
print("===Send Hello== ")
var fu =actServer!!ad
println("===Send ad==")
var result = fu()
**********************
Thread.sleep(5000)
}
}
}

  首先一定要重置classloader,否则又会报ClassNotFound。后面result就应该是接受回复的ActorDeal对象了,但fu()返回的是any对象,又如何转换为ActorDeal对象呢?

  请点击这里查看Scala如何类型强转 ,具体代码里面写的较为详细了。

  我们看看效果:

  

client init success
===Send Hello== ===Send ad==
From deal I have achieve target

  scala其他的特点,比如:强类型,扩展性这里就不一一描述了。

  

  上述的两点,应该属于scala与java之间最根本的特征了。

  

scala与java之间的那些事的更多相关文章

  1. scala 与 java 之间的关系

    scala来源于java,但又高于java. scala的设计者Martin Odersky就是一个JAVA控,这位牛人设计了javac和编写了jdk中的通用代码.可以说java语言本身就是Marti ...

  2. Java日志性能那些事(转)

    在任何系统中,日志都是非常重要的组成部分,它是反映系统运行情况的重要依据,也是排查问题时的必要线索.绝大多数人都认可日志的重要性,但是又有多少人仔细想过该怎么打日志,日志对性能的影响究竟有多大呢?今天 ...

  3. Scala For Java的一些参考

          变量 String yourPast = "Good Java Programmer"; val yourPast : String = "Good Java ...

  4. 使用Scala实现Java项目的单词计数:串行及Actor版本

    其实我想找一门“具有Python的简洁写法和融合Java平台的优势, 同时又足够有挑战性和灵活性”的编程语言. Scala 就是一个不错的选择. Scala 有很多语言特性, 建议先掌握基础常用的: ...

  5. scala调用java的方法,返回了一个对象链表List<Student>,在scala中遍历该链表获取指定Student的名字name

    假设Student类如下: class Student { private int no; private String name; public int getNo() { return no; } ...

  6. scala vs java 相同点和差异

    本贴是我摘抄自国外网站,用作备忘,也作为分享! Similarities between Scala and Java Following are some of the major similari ...

  7. Spark:用Scala和Java实现WordCount

    http://www.cnblogs.com/byrhuangqiang/p/4017725.html 为了在IDEA中编写scala,今天安装配置学习了IDEA集成开发环境.IDEA确实很优秀,学会 ...

  8. IDEA15使用maven编译scala和java

    机器安装maven,在IDEA中配置maven的home 创建项目:new-maven–> scala-archetype-simple project structure–>创建src. ...

  9. C#和java之间的一些差异与共性

    C#与java之间的一些共性和差异整理 隐藏:与java中的重写几乎一致,但是需要添加new关键字让编译器知道,否则会有警告 虚方法:1.声明为virtual的方法就是虚方法,在子类中使用overri ...

随机推荐

  1. 内网IPC$种马的三种方法

    copy muma.exe \\host\c$\windows\temp\foobar.exe ##IPC拷贝木马文件 WMIC远程运行命令 wmic /node:host /user:adminis ...

  2. Linux 常见安全检查方法

    Linux 常见安全检查方法进行概要说明: 一.检查系统密码文件,查看文件修改日期 # ls -l /etc/passwd 二.查看 passwd 文件中有哪些特权用户 # awk -F: '$3= ...

  3. Linux Oracle数据库的安装

    // 注释 # root用户 $oracle用户 1. 关闭安全措施    # chkconfig iptables off // 永久关闭防火墙 # serviceiptables stop // ...

  4. Android Studio Gradle项目中加入JNI so文件

    首先在Android Studio(版本号1.2.2)project的app文件夹下创建整个jni文件夹,jni文件夹里写Android.mk.Application.mk以及各类C/C++和汇编源文 ...

  5. Flex 自定义打印控件编写

    打印历来是web应用一个比较棘手的问题,幸好flex web应用是运行在flash player上的,flash player可以访问打印机,所以flex 应用可以实现比较强大的打印功能.Flex 自 ...

  6. JavaScript 屏蔽退格键

    document.onkeydown = function(){//屏蔽Backspace键 if (event.keyCode==8){ event.keyCode=0; event.returnV ...

  7. spring异常 java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderServlet

    spring异常 java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderServlet   情况 ...

  8. threw load() exception java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet(maven项目git后)

    maven项目git全新项目后启动服务出现的, 错误原因: 进入到tomcat的部署路径.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpw ...

  9. synchronized 锁优化

    synchronized 在jdk 1.7之前是重量级锁,独占锁,非公平锁.jdk1.7之后,synchronized引入了 偏向锁,自旋锁,轻量级锁,重量级锁 自旋锁 当线程在获取锁的时候,如果发现 ...

  10. 获取maven下resouce中的文件为File对象

    例如src/main/resources目录下面有个config/interfaces/quick-stock.xml文件我想直接在某一个Java类里面获取到这个文件的File对象,怎么整?(注意噢: ...