如何在Clojure中创建一个ArrayList

时间:2014-01-06 09:47:23

标签: java arraylist clojure

我需要在clojure中创建并填充ArrayList并将其传递给Java API。 有人可以帮助解释为什么以下两种方法存在差异(以及为什么其中一种方法不起作用)。

;;; this works
(defn make-an-array-list []
  (let [alist (java.util.ArrayList.)]
    (loop [x 0] (when (< x 6) (.add alist x) (recur (inc x)))) alist))
;;; ==> [0 1 2 3 4 5]

;;; this does not work
(defn make-an-array-list2 []
  (let [alist (java.util.ArrayList.)]
    (for [n (range 6)] (.add alist n)) alist))
;;; ==> []

或者,是否有任何建议代替上述方法?

3 个答案:

答案 0 :(得分:16)

更好的是,只需写(ArrayList. (range 6))即可。或者,如果java代码编写得很好,并且只需要Iterable,List或Collection - 任何不如ArrayList特定的东西 - 你只需返回(range 6)

答案 1 :(得分:4)

使用doseq代替懒惰的for。它有类似的绑定,但它的意思是副作用。

(defn make-an-array-list2 []
  (let [alist (java.util.ArrayList.)]
    (doseq [n (range 6)] (.add alist n)) alist))

;; [0 1 2 3 4 5]

答案 2 :(得分:3)

这是一个更明确的答案,为什么第二个例子不起作用。 for表达式是懒惰的;换句话说,除非其结果被某些东西消耗,否则不会对其进行评估。你丢弃了for表达式的结果,因为你只关心副作用,因此它实际上从未被评估过。

以下是同一现象的一个例子:

(defn example[] 
   (for [n (range 6)] 
      (println "n=" n))
   (println "done"))
(example)
;; done
;; nil