我想传递给java函数的地图。这些功能使用Java匿名类实现IFN接口。我还需要实现ISEQ接口以传递列表。ISEQ接口很简单,但没有文档。我需要知道ISEQ中的每种方法和/或找到实现所有ISEQ方法的类的Java代码(我不想将我的列表复制到Clojure结构(。
我需要知道ISEQ中的每种方法
您还应该了解它扩展的接口:
public interface Seqable {
ISeq seq(); // returns an ISeq instance
}
public interface IPersistentCollection extends Seqable {
// returns the count of this coll
int count();
// returns a new coll with o cons'd onto it
IPersistentCollection cons(Object o);
// returns a new empty coll (of same type?)
IPersistentCollection empty();
// compares this coll against o for equality
boolean equiv(Object o);
}
public interface ISeq extends IPersistentCollection {
// returns the first item in this seq
Object first();
// returns a new seq of every item in this except the first
ISeq next();
// returns a new seq of every item in this except the first
// ASeq returns empty for empty
ISeq more();
// returns a new seq with o cons'd onto this seq
ISeq cons(Object o);
}
...或找到实现所有ISEQ方法的类的Java代码
ASeq
抽象类实施(大多数(ISeq
。扩展ASeq
实现ISeq.next()
的类。
除了重新实现ISeq
外,还可以更简单地完成目标。也许查看Clojure的Java实现会给您一些想法。
问题文本的这个片段似乎表明在数组上调用 seq
,这是链接的答案对将Java数组转换为Clojure Seqs建议的问题,复制了内容的内容。阵列到新鲜的seq:
(我不想将我的列表复制到Clojure结构(
这是不是。相反,发生的是seq
返回由数组备份的包装器SEQ,如以下替补交互所证明:
Clojure 1.9.0
user=> (def xs (object-array [:foo :bar]))
#'user/xs
user=> (seq xs)
(:foo :bar)
user=> (def s1 (doall (seq xs)))
#'user/s1
user=> s1
(:foo :bar)
user=> (aset xs 0 :quux)
:quux
user=> (seq xs)
(:quux :bar)
user=> s1
(:quux :bar)
请注意,突变基础阵列会导致对突变之前创建的阵列的SEQ的可观察变化。
这与seq
的行为形成对比,当时通过java.util.List
并非同时是ISeq
,在这种情况下,确实会分配新的SEQ:
Clojure 1.9.0
user=> (def ys (java.util.ArrayList. [:foo :bar]))
#'user/ys
user=> ys
[:foo :bar]
user=> (def s2 (seq ys))
#'user/s2
user=> s2
(:foo :bar)
user=> (.set ys 0 :quux)
:foo
user=> ys
[:quux :bar]
user=> s2
(:foo :bar)
这不必是一个可怕的结果,因为SEQ会分解,但是避免任何包装可能是有意义的。
即使如此,还应检查确切的用法模式,因为可以将Java列表完全传递给Clojure并进行处理,而无需任何中间SEQ分配。例如,Iterable
S可以直接有效地为reduce
'D,而没有此类分配。
因此,我将重新检查以下假设:需要从Java侧传输到Clojure的列表需要作为ISeq
实例跨越鸿沟。这并不是说在任何情况下都没有任何安排是有道理的 - 仅仅是从问题文本中提供的有限细节来看,在这种特殊情况下这是必要的。
至于如何实施ISeq
,如果您决定最终这样做,我同意泰勒·伍德(Taylor Wood(的建议来检查clojure.lang.ASeq
。