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
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
相关文章推荐
- Programming Clojure学习笔记——与Java一起工作
- Programming Clojure学习笔记——与Java一起工作
- 一起学java【2】---一些必要的准备工作
- Programming Clojure学习笔记——与Java一起工作
- Java-2006工作手记
- 一起工作一起奋斗才是真的
- 工作的空余时间可以了解的java方面书籍
- 一起学Java_API-Scanner和String用法
- 一起Talk Android吧(第五回:Java中的程序结构)
- Spring boot 与 JdbcTemplate 一起工作
- 我的2013 - 工作九年JAVA程序员的选择与坚持
- 让Subversion和Visual Studio 2005一起工作
- 工作问题-java-三层数据结构
- 深入分析 Java I/O 的工作机制
- Java工作环境搭建
- java 执行 kettle5.0.1 转换与工作
- Java 并发专题 :闭锁 CountDownLatch 之一家人一起吃个饭
- 代码从svn到工作空间,Myeclipse中java项目转成Web项目
- 与受气包一起工作的日子
- PostgreSQL Replication之第八章 与pgbouncer一起工作(5)