Преобразование коллекций Java в структуры данных Clojure - PullRequest
5 голосов
/ 14 февраля 2012

Я создаю интерфейс Clojure для API Java с методом, который возвращает java.util.LinkedHashSet.

Во-первых, является ли идиоматический способ Clojure обрабатывать это для преобразования LinkedHashSet в структуру данных clojure?

Во-вторых, каков наилучший метод преобразования коллекций Java в структуры данных Clojure?

Ответы [ 3 ]

12 голосов
/ 14 февраля 2012

Вариантов много, поскольку Clojure прекрасно работает с коллекциями Java.Это зависит от того, какую именно структуру данных вы хотите использовать в Clojure.

Вот несколько примеров:

;; create a HashSet
(def a (java.util.HashSet.))
(dotimes [i 10] (.add a i))

;; Get all the values as a sequence 
(seq a)
=> (0 1 2 3 4 5 6 7 8 9)

;; build a new HashSet containing the values from a 
(into #{} a)
#{0 1 2 3 4 5 6 7 8 9}

;; Just use the HashSet directly (high performance, no copy required)
(.contains a 1)
=> true
(.contains a 100)
=> false

Что касается использования каждого из них, я бы предложил следующий совет:

  • Если вы пытаетесь обернутьбиблиотеку Java и представить чистый API Clojure, тогда я бы предложил преобразовать в эквивалентные структуры данных Clojure.Это то, что ожидают пользователи Clojure, и вы можете скрыть потенциально грязные детали взаимодействия Java.В качестве бонуса, это сделает вещи неизменными, так что вы не рискуете поменяться коллекциями Java во время их использования.
  • Если вы просто хотите использовать Java API быстро и эффективно, просто используйте взаимодействие Javaнепосредственно в коллекции Java.
2 голосов
/ 14 февраля 2012

Честно говоря, я не знаю, есть ли общепринятая практика, но вот Крис Хаузер спорит с адаптерами Java к Clojure, поскольку вы нарушаете совместимость с исходным Java API.

Для выполненияперевод, который вы просили, просто используйте в :

user=> (import java.util.LinkedHashSet)
java.util.LinkedHashSet
user=> (def x (LinkedHashSet.))
#'user/x
user=> (.add x "test")
true
user=> (def y (into #{} x))
#'user/y
user=> y
#{"test"}
2 голосов
/ 14 февраля 2012

Идиоматический способ преобразования java-коллекций в clojure заключается в использовании функции (seq), которая уже вызывается большинством функций, работающих с последовательностями.

(def s (java.util.LinkedHashSet.))
#'user/s
user> (seq s)
nil
user> (.add s "foo")
true
user> (seq s)
("foo")
user> 
...