简体   繁体   中英

How to make an ArrayList in Clojure

I need to create and populate an ArrayList in clojure and pass it to an Java API. Can someone help explain why there is a difference in the below two approaches (and why one of them doesn't work).

;;; 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))
;;; ==> []

Or, any suggestion in stead of the above approach?

Better still, just write (ArrayList. (range 6)) . Or if the java code is well written, and only requires an Iterable, List, or Collection - anything less specific than ArrayList - you can simply return (range 6) .

Use doseq instead of the lazy for . It has for-like bindings but it's meant for side-effects.

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

;; [0 1 2 3 4 5]

Here is a more explicit answer for why the second example doesn't work. The for expression is lazy; in other words, it isn't evaluated unless its result are consumed by something. You throw away the result of the for expression because you only care about the side-effects, so it's never actually evaluated.

Here is an example of the same phenomenon:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM