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

发布于 2025-01-05 23:39:47 字数 179 浏览 1 评论 0原文

我正在使用返回 java.util.LinkedHashSet 的方法创建 Java API 的 Clojure 接口。

首先,处理此问题的惯用 Clojure 方法是将 LinkedHashSet 转换为 clojure 数据结构吗?

其次,将 Java 集合转换为 Clojure 数据结构的最佳方法是什么?

I am creating a Clojure interface to a Java API with a method that returns a java.util.LinkedHashSet.

Firstly, is the idiomatic Clojure way of handling this to convert the LinkedHashSet to a clojure data structure?

Secondly, what is the best method for converting Java collections into Clojure data structures?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一影成城 2025-01-12 23:39:47

有很多选择,因为 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 库并提供干净的 Clojure API,那么我建议转换为等效的 Clojure 数据结构。这是 Clojure 用户所期望的,您可以隐藏潜在的混乱的 Java 互操作细节。作为奖励,这将使事物变得不可变,这样您就不会在使用 Java 集合时面临发生变化的风险。
  • 如果您只是想快速高效地使用 Java API,只需直接在 Java 集合上使用 Java 互操作即可。

There are lots of options, since Clojure plays very nicely with Java collections. It depends on exactly what data structure you want to use in Clojure.

Here's some examples:

;; 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

Regarding when to use each of these, I'd suggest the following advice:

  • If you are trying to wrap a Java library and present a clean Clojure API, then I'd suggest converting to the equivalent Clojure data structures. This is what Clojure users will expect, and you can hide the potentially messy Java interop details. As a bonus, this will make things immutable so that you don't run the risk of Java collections mutating while you use them.
  • If you just want to use the Java API quickly and efficiently, just use Java interop directly on the Java collections.
我很坚强 2025-01-12 23:39:47

将 java 集合转换为 clojure 的惯用方法是使用 (seq) 函数,大多数对序列进行操作的函数都已调用该函数。

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

The idiomatic way to convert java collections to clojure is to use the (seq) function, which is already called by most functions operating on sequences.

(def s (java.util.LinkedHashSet.))
#'user/s
user> (seq s)
nil
user> (.add s "foo")
true
user> (seq s)
("foo")
user> 
我也只是我 2025-01-12 23:39:47

老实说,我不知道是否存在普遍接受的做法,但 Chris Houser 争论 反对 Java 到 Clojure 适配器,因为您破坏了与原始 Java API 的兼容性。

要执行您要求的翻译,只需使用 into:

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"}

I honestly don't know if there's a universally accepted practice, but here's Chris Houser arguing against Java to Clojure adapters as you break compatibility with the original Java API.

To perform the translation you asked for, simply use into:

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"}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文