2016-04-14 10 views
4

Lassen Sie uns sagen, dass ich den folgenden Code haben:Wie unterscheidet man Java-Karte von Clojure Karte?

(def m1 (java.util.HashMap.)) 
(def m2 (java.util.LinkedHashMap.)) 
(def m3 {}) 

Ich brauche eine Funktion, die mir Karten zu erkennen, ermöglicht es, die von Java kam, z.B .:

(map java-map? [m1 m2 m3]) ;; => (true true false) 

Alles, was aus der Box?

+0

Haben Sie versucht, 'type' zu ​​verwenden? – jmargolisvt

Antwort

4

würde ich dies tun:

user=> (defn java-map? [m] 
     (and (instance? java.util.Map m) 
       (not (map? m)))) 
#'user/java-map? 

user=> (java-map? {}) 
false 

user=> (java-map? (java.util.HashMap.)) 
true 

user=> (java-map? []) 
false 

so überprüfen Sie nur, dass es Kern Java Map Schnittstelle implementiert, aber kein clojure beharrliche Karte zu sein.

+0

Das scheint mir legitim. – OlegTheCat

8

Sie können map? verwenden zu überprüfen, ob etwas IPersistentMap implementiert, die für Clojure Karten wahr ist, aber nicht für java.utils.* Karten:

(map? (java.util.HashMap.)) ;; => false 
(map? (java.util.LinkedHashMap.)) ;; => false 
(map? {}) ;; => true 

Um genauer zu sein, sollten Sie lieber prüfen, ob ein bestimmtes Objekt einige Anforderungen erfüllt (zB ist hartnäckig, unveränderlich/veränderbar - map? wird diese spezifische Frage beantworten). Es gibt keine einfache Möglichkeit zu sagen, ob Sie eine Java-Implementierung einer Map erhalten haben, da Sie eine andere Implementierung aus einer externen Bibliothek mit einer benutzerdefinierten Implementierung von java.util.Map erhalten oder eine der konkreten Implementierungen aus dem Paket java.util erweitern können.

+1

Ja, dachte eigentlich über die Verwendung von 'map?' Nach, aber '(def java-map? (Komplement-Map?))' - dies ergibt falsche Ergebnisse bei Objekten anderer Typen: '(java-map? []) ;; => true' – OlegTheCat

+1

Ja, Sie haben Recht, lassen Sie mich diesen Teil der Antwort entfernen, wie es falsch ist. –

+0

Ich glaube, da könnte man auch ein 'Protokoll' oder' Multimethods' verwenden, um per Eingabetyp zu versenden –