scala与java之间的那些事

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.可传递
  

 1 def  func(f:()  =>  String)  =  println(f())
 2 func(()  =>  "hi")
 3 //output:  hi
 4
 5 def  foo()  =  "ok"
 6 func(foo)
 7 //output:  ok
 8
 9 val  fun  =  (x:Int)  =>  print(x)
10 fun(2)
11 //output:2

  2.嵌套函数

1 def foo(){
2     def bar(){
3         println("hi")
4         }
5     bar  //exec
6 }
7
8 foo //output:hi        

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

 1 def fun1(){
 2   .....
 3   this
 4 }
 5
 6 def fun2(){
 7   ....
 8   this
 9 }
10
11 //两个函数可以如下方式使用
12 fun1().fun2()

  3.匿名函数

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

  4.高阶函数

 1 第一种:用函数做参数的函数。eg:
 2
 3 def f2(f:() => Unit) {f()}
 4
 5 def f1(){println(1)}
 6
 7 f2(f1)
 8
 9 f2(() => println("hi")) //传入匿名函数
10
11 第二种:产生的结果是一个函数的函数。eg:
12
13 def hf():Int => Int = x => x +1
14
15 val fun = hf
16
17 fun(2) //output:3

  5.函数柯里化

 1 当函数具有多个参数时
 2 def sum(x:Int,y:Int) = x + y
 3
 4 //参数被打散后,两个参数分开
 5 def sum2(x:Int)(y:Int) = x + y
 6
 7 sum2(1)(2) //output:3
 8
 9 scala> def first(x:Int)=(y:Int) => x+y
10 first: (x: Int)Int => Int
11
12 scala> first(1)
13 res10: Int => Int = <function1>
14
15 scala> val second=first(1)
16 second: Int => Int = <function1>
17
18 scala> second(2)
19 res11: Int = 3
20
21 函数链
22 把一个带有多个参数的函数,转换为多个只有一个参数的函数来执行
23
24 f(1)(2)(3) 相当于 ((f(1))(2))(3)
25
26 带入参数 1执行 fa(1) 然后 带入参数2执行 fb(2) 接着带入参数3执行fc(3) 最后得到结果
27
28 柯里化的实际用途?
29 控制抽象,可改变代码的书写风格 foo(res,()=>println(res)) foo(res)(()=> println(res)) foo(res){()=> println(res)}
30 实现部分应用函数
31 scala> def log(time:java.util.Date,msg:String){println(time+msg)}
32 log: (time: java.util.Date, msg: String)Unit
33
34 scala> val log2 = log(new java.util.Date,_:String)
35 log2: String => Unit = <function1>
36
37 scala> log2("test1")
38 Mon Sep 09 23:46:15 CST 2013test1
39
40 scala> log2("test2")
41 Mon Sep 09 23:46:19 CST 2013test2
42
43 scala> log2("test3")
44 Mon Sep 09 23:46:22 CST 2013test3

  6.闭包

 1 在java中匿名内部类访问局部变量是,局部变量必须声明为final(类似闭包的实现)
 2
 3 scala中没有那么麻烦:
 4
 5 scala> val more = 1
 6 more: Int = 1
 7
 8 scala> val addMore = (x: Int) => x + more
 9 addMore: Int => Int = <function1>
10
11 scala> addMore(10)
12 res19: Int = 11

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

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

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

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

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

  典型的actor编程模型如下:

  

 1 Scala写法1:
 2
 3 import actors.Actor,actors.Actor._
 4
 5 class A1 extends Actor {
 6
 7 def act {
 8     react {
 9         case n:Int=>println(perfect(n))
10         }
11     }
12 }
13
14 n to n+10 foreach (i=>{
15     (new A1).start ! i
16     }
17 )
1 val aa = Array.fill(11)(actor {
2     react {
3         case n:Int=>println(perfect(n))
4         }
5     }
6 )
7
8 n to n+10 foreach (i=>aa(i-n) ! i)

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

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

 1 服务器端:
 2
 3 object ActorServer extends Application {
 4
 5     import actors.Actor, actors.Actor._, actors.remote.RemoteActor
 6
 7     Actor.actor { // 创建并启动一个 actor
 8
 9       // 当前 actor 监听的端口: 3000
10
11       RemoteActor.alive(3000)
12
13
14
15       // 在 3000 端口注册本 actor,取名为 server1。
16
17       // 第一个参数为 actor 的标识,它以单引号开头,是 Scala 中的 Symbol 量,
18
19       // Symbol 量和字符串相似,但 Symbol 相等是基于字符串比较的。
20
21       // self 指代当前 actor (注意此处不能用 this)
22
23       RemoteActor.register(‘server1, Actor.self)
24
25
26
27       // 收到消息后的响应
28
29       loop {
30
31         Actor.react {case msg =>
32
33           println("server1 get: " + msg)
34
35         }
36
37       }
38
39     }
40
41 }
42
43
44
45 客户端:
46
47
48
49 object ActorClient extends Application {
50
51     import actors.Actor, actors.remote.Node, actors.remote.RemoteActor
52
53     Actor.actor {
54
55       // 取得一个节点(ip:port 唯一标识一个节点)
56
57       // Node 是个 case class,所以不需要 new
58
59       val node = Node("127.0.0.1", 3000)
60
61
62
63       // 取得节点对应的 actor 代理对象
64
65       val remoteActor = RemoteActor.select(node, ‘server1)
66
67
68
69       // 现在 remoteActor 就和普通的 actor 一样,可以向它发送消息了!
70
71       println("-- begin to send message")
72
73       remoteActor ! "ActorClient的消息"
74
75       println("-- end")
76
77     }
78
79 }

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

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

  

时间: 2024-08-04 15:29:34

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

Java调试那点事

转自: http://yq.aliyun.com/articles/56?hmsr=toutiao.io&spm=5176.100240.searchblog.18&utm_medium=toutiao.io&utm_source=toutiao.io Java调试那点事 该文章来自于阿里巴巴技术协会(ATA)精选文章. Java调试概述 程序猿都调式或者debug过Java代码吧?都体会过被PM,PD,测试,业务同学们围观debug吧?说调试,先看看调试严格定义是什么.引用Wik

关于JAVA多线程的那些事__初心者

前言 其实事情的经过也许会复杂了点,这事还得从两个月前开始说.那天,我果断不干IT支援.那天,我立志要做一个真正的程序猿.那天,我26岁11个月.那天,我开始看Android.那天,我一边叨念着有朋自远方来,一边投身了JAVA的怀抱.那天,一切将会改变. 好吧,反正总的来说就是时隔4年半,我又开始搞JAVA了.Eclipse还是Eclipse:NetBeans还是NetBeans:Java被收之后已经来到了7,现在是8:在入手了几本JAVA的书籍后发现<JAVA编程思想>还是这么伟大:开始了新

Spark:用Scala和Java实现WordCount

为了在IDEA中编写scala,今天安装配置学习了IDEA集成开发环境.IDEA确实很优秀,学会之后,用起来很顺手.关于如何搭建scala和IDEA开发环境,请看文末的参考资料. 用Scala和Java实现WordCount,其中Java实现的JavaWordCount是spark自带的例子($SPARK_HOME/examples/src/main/java/org/apache/spark/examples/JavaWordCount.java) 1.环境 OS:Red Hat Enterp

Scala入门到精通——第二十八节 Scala与JAVA互操作

本节主要内容 JAVA中调用Scala类 Scala中调用JAVA类 Scala类型参数与JAVA泛型互操作 Scala与Java间的异常处理互操作 1. JAVA中调用Scala类 Java可以直接操作纵Scala类,如同Scala直接使用Java中的类一样,例如: //在Person.scala文件中定义Scala语法的Person类 package cn.scala.xtwy.scalaToJava class Person(val name:String,val age:Int) //伴

Scala与Java交互

Scala的一个强项在于可以很简单的于已有的Java代码交互,所有java.lang中的类都已经被自动导入了,而其他的类需要显式声明导入.来看看演示代码吧.我们希望对日期进行格式化处理,比如说用法国的格式.Java类库定义了一系列很有用的类,比如Date和DateFormat.由于Scala于Java能够进行很好的交互,我们不需要在Scala类库中实现等效的代码,而只需直接吧Java的相关类导入就可以了:import java.util.{Date, Locale}import java.tex

编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本]

编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本] 1. 开发环境 Jdk 1.7.0_72 Maven 3.2.1 Scala 2.10.6 Spark 1.6.2 Hadoop 2.6.4 IntelliJ IDEA 2016.1.1 2. 创建项目1) 新建Maven项目 2) 在pom文件中导入依赖pom.xml文件内容如下: <?xml version="1.0" encoding="UTF-8"?> &l

java序列化Serializable那些事

串行化也叫序列化,就是将实例的状态转化成文本(或二近制)的形式,以便永久保存(所以有时候也叫持久化,或者信息的冷藏等等)或在网间传递.也就是说,如果一个类的实例需要持久化或者需要在网间传递的时候,就用到了串行化  Serialization是指把类或者基本的数据类型持久化(persistence)到数据流(Stream)中,包括文件.字节流.网络数据流.         JAVA中实现serialization主要靠两个类:ObjectOuputStream和ObjectInputStream.

Linux 环境下思源黑体字体与 Java 之间的兼容性问题的解决(补充说明)

在前一篇随笔中,我讲了一下有关 Linux 环境下思源黑体与 Java 之间的兼容性问题,后来经过测试发现,默认安装的思源黑体字体同时包含简体字体和繁体字体,并且其对应的语言编码也是不同的.尝试着把繁体字体卸载掉后,Java 程序可以正常显示思源黑体字形了.但即使这样,仍然存在一个问题,在 Java Swing 类型的程序中(比如 NetBeans.IDEA 等)如果你明确选择思源黑体作为编辑字体,则编辑区域无法显示任何内容,可以理解为思源黑体在 Java 内部字体栅格化处理方面仍然有点兼容性问

&lt;监听器模式&gt;在C++ 与 Java 之间实现的差异

前言: 关于各种语言孰优孰劣的讨论在软件界就是个没完没了的话题,今天我决定也来掺和下.不过我想探讨的不是哪种语言的性能如何,钱途如何,而是站在语言本身特性的基础上中肯地比较探讨.因为现在工作用的是C/C++, 以前接触过Java,于是我就以这两门语言作为我的对比语言. 本文目的: 我就以监听器的实现为例演示各自的实现代码,认识下Java与C++的代码风格,看看Java是如何滋润地生活在无指针的环境下,瞄瞄指针在C++中又有如何妙用? 场景设计:         以监听器模式为例,现在有一个Win