2010-11-30 2 views
37

Что такое Clojure-идиоматических способ преобразовать структуру данных в коллекции Java, а именно:Преобразование структуры данных Clojure в Java коллекции

  • [] к java.util.ArrayList
  • {} к java.util.HashMap
  • #{} до java.util.HashSet
  • () до java.util.LinkedList

Возможно, существует библиотека clojure.contrib?

USE CASE: Чтобы облегчить Clojure в моей организации, я рассматриваю возможность написания пакета unit-test для сервера все-Java REST в Clojure. Я написал часть пакета в Scala, но думаю, что Clojure может быть лучше, потому что поддержка макроса уменьшит количество кода шаблона (мне нужно протестировать десятки подобных вызовов службы REST).

Я использую EasyMock для подделки соединений с базой данных (есть ли лучший способ?), И мои издеваемые методы должны возвращать вызывающим абонентам java.util.List<java.util.Map<String, Object>> элементов (представляющих набор строк базы данных). Я передал бы в структуру [{ "first_name" "Joe" "last_name" "Smith" "date_of_birth" (date "1960-06-13") ... } ...] свой макет и преобразовал бы его в требуемую коллекцию Java, чтобы она могла быть возвращена вызывающему в ожидаемом формате.

+6

Если методы должны возвращать `java.util.List`, то нет никакой необходимости, чтобы преобразовать так как Clojure vector * является * `List`. Вам нужно только преобразовать, если требуемый тип имеет определенный класс реализации, например. `ArrayList`. – 2010-11-30 18:23:11

ответ

65

Clojure вектор, набор и список классов реализуют интерфейс java.util.Collection и ArrayList, HashSet и LinkedList может занять java.util.Collection аргумент конструктора. Таким образом, вы можете просто сделать:

user=> (java.util.ArrayList. [1 2 3]) 
#<ArrayList [1, 2, 3]> 
user=> (.get (java.util.ArrayList. [1 2 3]) 0) 
1 

Аналогично, Clojure карта класс реализует интерфейс java.util.Map и HashMap принимает java.util.Map аргумент конструктора. Итак:

user=> (java.util.HashMap. {"a" 1 "b" 2}) 
#<HashMap {b=2, a=1}> 
user=> (.get (java.util.HashMap. {"a" 1 "b" 2}) "a") 
1 

Вы также можете сделать наоборот, и это гораздо проще:

ser=> (into [] (java.util.ArrayList. [1 2 3])) 
[1 2 3] 
user=> (into #{} (java.util.HashSet. #{1 2 3})) 
#{1 2 3} 
user=> (into '() (java.util.LinkedList. '(1 2 3))) 
(3 2 1) 
user=> (into {} (java.util.HashMap. {:a 1 :b 2})) 
{:b 2, :a 1} 
+0

Я этого не знал. Отлично. Благодарю. – Ralph 2010-11-30 12:41:36

Смежные вопросы