Ich arbeite in Clojure mit einer Java-Klasse, die eine Retrieval-API für eine domänenspezifische Binärdatei mit einer Reihe von Datensätzen bietet.Interop von clojure a mit nicht-standard iterativen Java API
Die Java-Klasse wird mit einer Datei initialisiert und stellt dann eine .query
-Methode bereit, die eine Instanz einer inneren Klasse zurückgibt, die nur eine Methode .next
hat und daher nicht gut mit der üblichen Java-Auflistungs-API zusammenspielt. Weder die äußere noch die innere Klasse implementiert irgendeine Schnittstelle.
Die .query
-Methode kann null anstelle der inneren Klasse zurückgeben. Die Methode .next
gibt eine Datensatzzeichenfolge oder null zurück, wenn keine weiteren Datensätze gefunden werden. Sie kann sofort nach dem ersten Aufruf null zurückgeben.
Wie mache ich diese Java-API gut aus clojure, ohne weitere Java-Klassen zu schreiben?
Das Beste, was ich tun konnte, ist:
(defn get-records
[file query-params]
(let [tr (JavaCustomFileReader. file)]
(if-let [inner-iter (.query tr query-params)] ; .query may return null
(loop [it inner-iter
results []]
(if-let [record (.next it)]
(recur it (conj results record))
results))
[])))
Das gibt mir einen Vektor der Ergebnisse mit der clojure ff Abstraktionen zu arbeiten. Gibt es andere Möglichkeiten, einen Seq von der Java-API zu offenbaren, entweder mit Lazy-Seq oder mit Protokollen?
Dies ist eine interessante Frage, aber was meinen Sie mit einer nicht standardmäßigen Java API? – octopusgrabbus
@octopusgrabbus speziell ich meine, der Java-Code bietet keinen java.util.Iterator noch java.lang.Iterable zu implementieren. Logischerweise bietet der Java-Code eine Iteration, jedoch ohne eine Verbindung zur Standard-API. –