[英]Make a Java class work as a sequence in Clojure
I am using a Java class that represents a sequence of results (somewhat like a Clojure vector). 我使用的Java类代表一系列结果(有点像Clojure向量)。
I would like to use this class with the typical Clojure sequence functions (ie I want to have the class behave as if it supported the sequence abstraction) however I can't change the class so am unable to make it implement clojure.lang.Seqable
or similar. 我想将这个类与典型的Clojure序列函数一起使用(即我希望该类的行为就像它支持序列抽象一样)但是我无法更改类,所以我无法使它实现clojure.lang.Seqable
或类似的。 Also, annoyingly, the class does not implement java.util.Collection
or java.lang.Iterable
. 另外,令人讨厌的是,该类没有实现java.util.Collection
或java.lang.Iterable
。
I can see a few options: 我可以看到几个选项:
iterator-seq
on the object's (existing) iterator. 在对象的(现有)迭代器上使用iterator-seq
。 java.util.Collection
/ clojure.lang.Sequable
将对象包装在另一个实现java.util.Collection
/ clojure.lang.Sequable
类java.util.Collection
Are there any other options? 还有其他选择吗? What is the best approach? 什么是最好的方法?
The fastest and most straightforward would be to use iterator-seq
. 最快和最直接的方法是使用iterator-seq
。
This does beg the question: Why doesn't core Clojure provide a protocol like SeqSource that would be called by seq
. 这确实最难解决的问题:为什么没有核心的Clojure提供的协议一样SeqSource将由调用seq
。 Then non-standard collections could be "extended" to supply a seq, similar to how the InternalReduce works for reduce
. 然后可以“扩展”非标准集合以提供seq,类似于InternalReduce如何用于reduce
。
使用proxy
来扩展类并使其实现ISeq
My first shot would be to create lazy-seq of that object: 我的第一个镜头是创建该对象的lazy-seq:
(defn sequify [obj]
(letfn [(inner [idx]
(when (< idx (.size obj))
(cons (.get obj idx)
(lazy-seq
(inner (inc idx))))))]
(inner 0)))
Just replace .size
and .get
with appropriate methods. 只需用适当的方法替换.size
和.get
。
Writing a wrapper may be more appropriate if you want to improve performance compared to lazy-seq
solution. 如果您想要与lazy-seq
解决方案相比提高性能,编写包装器可能更合适。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.