简体   繁体   English

使Java类在Clojure中作为序列工作

[英]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.Collectionjava.lang.Iterable

I can see a few options: 我可以看到几个选项:

  • Use iterator-seq on the object's (existing) iterator. 在对象的(现有)迭代器上使用iterator-seq
  • Wrap the object in another class that implements java.util.Collection / clojure.lang.Sequable 将对象包装在另一个实现java.util.Collection / clojure.lang.Sequablejava.util.Collection
  • Create a function that builds a Clojure vector or sequence by querying the Object 创建一个通过查询Object来构建Clojure向量或序列的函数

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM