您的位置:首页 > 编程语言 > Java开发

Programming Clojure学习笔记——与Java一起工作

2011-12-17 19:08 573 查看
3.1 调用Java

Clojure提供了简单直接的语法调用Java代码:创建对象,调用方法,访问静态方法和属性。

访问构造函数,方法和属性

Clojure提供了new形式调用构造函数创建实例

(new classname)

下面的代码创建Ramdom对象,赋给rnd变量:

user=> (def rnd (new java.util.Random))

#'user/rnd

使用特殊形式(.)调用方法:

(. class-or-instance member-symbol & args)

(. class-or-instance (member-symbo & args))

下面的代码调用rnd的nextInt方法:

user=> (. rnd nextInt)

-1663716284

特殊形式(.)可以作用在静态或实例属性和方法上。如:

user=> (. Math PI)

可以通过import显示引入类,使用时就可以不需要用类全名称:

(import [& import-lists])

在Clojure中调用Java大致分为以下几步:

1. 引入类名

2. 创建实例

3. 访问实例属性

4. 调用实例方法

语法糖

大部分Java形式都有一个缩写形式,如

(1) new形式可以缩写为Classname.

(new Random)可以缩写为(Random.)

(2) 对于静态域,缩写形式Classname/membername,如

(. Math PI)可以缩写为Math/PI

(3) 同样对于静态方法,也可以缩写为(Classname/membername),如

(System/currentTimeMillis)

(4) .形式的缩写形式.methodOrFieldName,如

(. rnd nextInt)可以缩写为(.nextInt rnd)

(5) 多次连续调用的缩写形式(.. class-or-instance form & forms),如

(.getLocation (.getCodeSource (.getProtectionDomain (.getClass '(1 2)))))可以缩写为

(.. '(1 2) getClass getProtectionDomain getCodeSource getLocation)

(6) 在同一对象上调用多个方法(doto class-or-inst & member-access-forms),如

(doto (System/getProperties)

(.setProperty "name" "Stuart")

(.setProperty "favoriteColor" "blue"))

使用Java集合

Clojure提供make-array函数创建Java数组:

创建一维数组 (make-array class length),如

user=> (make-array String 5)

#<String[] [Ljava.lang.String;@5f6303>

创建多维数组 (make-array class dim & more-dims),如

user=> (make-array String 2 2)

#<String[][] [[Ljava.lang.String;@766a24>

可以使用seq将任意Java数组包装称Clojure序列,如

user=> (seq (make-array String 5))

(nil nil nil nil nil)

Clojure还提供了一序列类似int-array的函数用来创建Java基础类型数组,如

user=> (int-array 5)

#<int[] [I@1742700>

Clojure提供了一组Java数组基本操作函数:

aset 设置Java数组项值

一维数组 (aset java-array index value)

多维数组 (aset java-array index-dim1 index-dim2 ... value)

aget 获取Java数组项值

一维数组 (aget java-array index)

多维数组 (aget java-array index-dim1 index-dim2 ...)

alength获取数字长度

(alength java-array)

示例:

user=> (defn painstakingly-create-array []

(let [arr (make-array String 5)]

(aset arr 0 "Painstaking")

(aset arr 1 "to")

(aset arr 2 "fill")

(aset arr 3 "in")

(aset arr 4 "arrays")

arr))

#'user/painstakingly-create-array

user=> (aget (painstakingly-create-array) 0)

"Painstaking"

user=> (alength (painstakingly-create-array))

5

to-array函数直接将集合转化为数组

(to-array sequence)

说明:转换的结果为Object数组

user=> (to-array ["Easier" "array" "creation"])

#<Object[] [Ljava.lang.Object;@cf66b>

into-array函数也能将集合转换为数组,并且可以指定数组元素类型

(into-array type? seq),如:

user=> (into-array String ["Easier" "array" "creation"])

#<String[] [Ljava.lang.String;@110c31>

如果忽略类型参数,into-array则根据第一个元素猜测数组元素的类型,如:

user=> (into-array ["Easier" "array" "creation"])

#<String[] [Ljava.lang.String;@110c31>

amap函数转换Java数组的每个元素

(amap a idx ret expr)

amap创建数组的克隆,并绑定到变量ret,对数组a每一个元素执行expr表达式,idx绑定到数组元素索引,最后返回克隆的数组,如

user=> (def strings (into-array ["some" "strings" "here"]))

#'user/strings

user=> (seq (amap strings idx _ (.toUpperCase (aget strings idx))))

("SOME" "STRINGS" "HERE")

areduce函数类似amap,但可以返回值任意

(areduce a idx ret init expr)

areduce开始用init初始化ret,然后对每一个数组a元素计算表达式expr,将计算结果赋给ret返回。如

user=> (areduce strings idx ret 0 (max ret (.length (aget strings idx))))

7

上面的代码计算数组strings中,最长字符串的长度

便利函数

1. memfn 创建匿名函数包装Java方法,使其在Clojure中能像Clojure函数那样使用,如

user=> (map (memfn toUpperCase) ["a" "short" "message"])

("A" "SHORT" "MESSAGE")

还可以写成如下形式:

user=> (map #(.toUpperCase %) ["a" "short" "message"])

("A" "SHORT" "MESSAGE")

2. instance? 类似Java的instanceof,检测一个对象是否是某个类的实例,如

user=> (instance? Integer 10)

true

3. format包装了Java的format方法,格式化字符串

(format fmt-string & args),如

user=> (format "%s ran %d miles today" "Stu" 8)

"Stu ran 8 miles today"

说明:占位符详细参考Java相关文档

4. bean包装JavaBean将其转换为不可变的Clojure映射

(bean java-bean),如

user=> (import '(java.security MessageDigest))

java.security.MessageDigest

user=> (bean (MessageDigest/getInstance "SHA"))

{:provider #<Sun SUN version 1.6>, :digestLength 20, :class java.security.Messag

eDigest$Delegate, :algorithm "SHA"}

user=> (:digestLength (bean (MessageDigest/getInstance "SHA")))

20
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: