将 Clojure 数据结构转换为 Java 集合

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4313505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 05:48:56  来源:igfitidea点击:

Converting Clojure data structures to Java collections

javadata-structurescollectionsclojure

提问by Ralph

What is the Clojure-idiomatic way to convert a data structure to a Java collection, specifically:

将数据结构转换为 Java 集合的 Clojure 惯用方法是什么,具体来说:

  • []to a java.util.ArrayList
  • {}to a java.util.HashMap
  • #{}to a java.util.HashSet
  • ()to a java.util.LinkedList
  • []java.util.ArrayList
  • {}java.util.HashMap
  • #{}java.util.HashSet
  • ()java.util.LinkedList

Is there a clojure.contrib library to do this?

是否有 clojure.contrib 库可以做到这一点?

USE CASE: In order to ease Clojure into my organization, I am considering writing a unit-test suite for an all-Java REST server in Clojure. I have written part of the suite in Scala, but think that Clojure may be better because the macro support will reduce a lot of the boilerplate code (I need to test dozens of similar REST service calls).

用例:为了让 Clojure 轻松融入我的组织,我正在考虑为 Clojure 中的全 Java REST 服务器编写单元测试套件。我已经用 Scala 编写了部分套件,但认为 Clojure 可能会更好,因为宏支持会减少大量样板代码(我需要测试几十个类似的 REST 服务调用)。

I am using EasyMock to mock the database connections (is there a better way?) and my mocked methods need to return java.util.List<java.util.Map<String, Object>>items (representing database row sets) to callers. I would pass in a [{ "first_name" "Joe" "last_name" "Smith" "date_of_birth" (date "1960-06-13") ... } ...]structure to my mock and convert it to the required Java collection so that it can be returned to the caller in the expected format.

我正在使用 EasyMock 来模拟数据库连接(有更好的方法吗?)并且我的模拟方法需要将java.util.List<java.util.Map<String, Object>>项目(代表数据库行集)返回给调用者。我会将一个[{ "first_name" "Joe" "last_name" "Smith" "date_of_birth" (date "1960-06-13") ... } ...]结构传递给我的模拟并将其转换为所需的 Java 集合,以便它可以以预期的格式返回给调用者。

回答by Abhinav Sarkar

Clojure vector, set and list classes implement the java.util.Collectioninterface and ArrayList, HashSetand LinkedListcan take a java.util.Collectionconstructor argument. So you can simply do:

Clojure 向量、集合和列表类实现java.util.Collection接口 and ArrayListHashSet并且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

Similarly, Clojure map class implements java.util.Mapinterface and HashMaptakes a java.util.Mapconstructor argument. So:

类似地,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

You can also do the reverse and it is much easier:

你也可以做相反的事情,它更容易:

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}