Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使Java类在Clojure中作为序列工作_Java_Clojure_Sequence_Clojure Java Interop - Fatal编程技术网

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

使Java类在Clojure中作为序列工作,java,clojure,sequence,clojure-java-interop,Java,Clojure,Sequence,Clojure Java Interop,我使用的Java类表示一系列结果(有点像Clojure向量) 我希望将该类与典型的Clojure序列函数一起使用(即,我希望该类的行为就像它支持序列抽象一样),但是我无法更改该类,因此无法使其实现Clojure.lang.Seqable或类似功能。另外,令人烦恼的是,该类没有实现java.util.Collection或java.lang.Iterable 我可以看到一些选择: 在对象的(现有)迭代器上使用迭代器seq 将对象包装到另一个实现java.util.Collection/cloju

我使用的Java类表示一系列结果(有点像Clojure向量)


我希望将该类与典型的Clojure序列函数一起使用(即,我希望该类的行为就像它支持序列抽象一样),但是我无法更改该类,因此无法使其实现
Clojure.lang.Seqable
或类似功能。另外,令人烦恼的是,该类没有实现
java.util.Collection
java.lang.Iterable

我可以看到一些选择:

  • 在对象的(现有)迭代器上使用
    迭代器seq
  • 将对象包装到另一个实现
    java.util.Collection
    /
    clojure.lang.Sequable
  • 创建一个函数,通过查询对象来构建Clojure向量或序列

还有其他选择吗?最好的方法是什么?

最快、最直接的方法是使用
迭代器seq


这就引出了一个问题:为什么core Clojure不提供类似SeqSource的协议,由
seq
调用。然后可以“扩展”非标准集合以提供seq,类似于InternalReduce如何为
reduce
扩展类并使其实现
ISeq
我的第一步是创建该对象的惰性seq:

(defn sequify [obj]
  (letfn [(inner [idx] 
                 (when (< idx (.size obj))
                          (cons (.get obj idx)
                                (lazy-seq 
                                  (inner (inc idx))))))]
    (inner 0)))
(定义如下[obj]
(letfn[(内部[idx]
(当(
只要用适当的方法替换
.size
.get


如果您想与
lazy seq
解决方案相比提高性能,那么编写包装器可能更合适。

迭代器seq
似乎不错,在内部,它与您关于包装对象的第二点做的事情相同,因为seq是编译器使用的(a),因此需要是java友好的(即接口),而且(b)调用得非常频繁,所以它需要尽可能快-协议比很多东西都快,但没有简单的接口调度那么快。@amalloy然后可能会使用a
to seq
函数来代替“另外,令人烦恼的是,类没有实现java.util.Collection或java.lang.Iterable。”@noahz但是,从最初的问题来看,“对象的(现有)迭代器”意味着有一个迭代器可用。考虑到这一点,创建代理似乎有些过分。如果没有迭代器,那么当然可以使用其他方法将名为
的函数添加到seq
中,该函数的作用与
seq
相同,根本无法解决任何问题。它仍然需要被编译器访问,当然没有clojure函数是可访问的。