2012-02-01 8 views
10

में कोई ऑब्जेक्ट जावा प्राइमेटिव सरणी है या नहीं, यह पता लगाने का सबसे अच्छा तरीका क्या है कि ऑब्जेक्ट क्लोजर में जावा आदिम सरणी है या नहीं?क्लोजर

कारण मैं की जरूरत है इस आदिम सरणियों के लिए कुछ विशेष हैंडलिंग करना है, जो की तरह कुछ दिख सकता है:

(if (byte-array? object) 
    (handle-byte-array object)) 

यह कोड का एक काफी प्रदर्शन के प्रति संवेदनशील टुकड़ा में है, इसलिए मैं नहीं बल्कि प्रतिबिंब से बचने के हैं तो बिल्कुल भी संभव है।

+1

सुनिश्चित नहीं है कि क्लोजर कोड क्या होगा, लेकिन आप प्रत्येक आदिम प्रकार के लिए खाली सरणी बना सकते हैं, उन पर getClass() को कॉल कर सकते हैं, और परिणामों को कैश कर सकते हैं। क्लास ऑब्जेक्ट उस आदिम प्रकार की प्रत्येक सरणी के लिए समान होना चाहिए - आप कैश किए गए लोगों की तुलना 'object.getClass() 'से करेंगे।(getClass() वास्तव में धीमी कॉल नहीं होना चाहिए) – millimoose

उत्तर

8

आप एक बार प्रतिबिंब का उपयोग कर सकते नाम से कक्षा प्राप्त करने के लिए, कैश और फिर इस कि

(def array-of-ints-type (Class/forName "[I")) 
(def array-of-bytes-type (Class/forName "[B")) 
... 

(= (type (into-array Integer/TYPE [1 3 4])) array-of-ints-type) 
true 
+0

नाइस, आदिम सरणी कक्षाओं को कैशिंग करने के विचार की तरह। हालांकि यह मुझे थोड़ा सा हड़ताल करता है कि ये जावा में कहीं भी परिभाषित नहीं हैं! – mikera

+0

और जो उस पर "[मैं" नाम से आया था ... –

+3

'" [जे "' 'लंबी 'के लिए और भी अधिक प्यारा है, है ना? साथ ही, जो भी '.toString' वापसी मूल्यों में बेजोड़ उद्घाटन ब्रैकेट के साथ आया था, कभी भी मैं उनका नाम सीखता हूं, मेरा पिचफर्क तैयार हो जाएगा। यह हर समय मेरे लिए paredit तोड़ता है, उल्लेख नहीं है [मेरे मनोविज्ञान पर प्रभाव] (http://xkcd.com/859/)। (सभी प्रासंगिक मामलों के लिए 'प्रिंट-विधि' को बदलना संभव हो सकता है या नहीं भी हो सकता है - मेरी वर्तमान आंत महसूस * नहीं *।) –

7
(defn primitive-array? [o] 
    (let [c (class o)] 
    (and (.isArray c) 
     (.. c getComponentType isPrimitive)))) 

विशेष मामलों के लिए करने के लिए बाकी की तुलना, आप निम्न की तरह कुछ इस्तेमाल कर सकते हैं:

(defn long-array? [o] 
    (let [c (class o)] 
    (and (.isArray c) 
     (identical? (.getComponentType c) Long/TYPE)))) 
+0

सभी रहस्य बेकार हैं: http://docs.oracle.com/javase/6 /docs/api/java/lang/Class.html – Bill

4

या सादे पुराने instance?:

(instance? (RT/classForName "[B") thing) 
+0

'आरटी' के लिए आप किस उपनाम का उपयोग कर रहे हैं? आपका मतलब है '(कक्षा/के लिए नाम "[बी")' सही? –

+0

@ डेविडजम्स आरटी clojure.lang.RT है। – kotarak

4

आर्थर Ulfeldt द्वारा बताया के रूप में, तुम यहाँ की तरह Class/forName उपयोग कर सकते हैं, उदाहरण के लिए,:

(def byte_array_class (Class/forName "[B")) 

(defn byte-array? [arr] (instance? byte_array_class arr)) 

आप "[B" की तरह जादू तार से बचना चाहते हैं जब कक्षाएं कैशिंग, आप एक मौजूदा सरणी के लिए आवेदन कर सकते हैं class वस्तु:

(def byte_array_class (class (byte-array []))) 
+1

यहां तक ​​कि सरल: '(डीईटी बाइट-एरे-क्लास (कक्षा (बाइट-सर 0)))'। (कोई भी अंडरस्कोर नहीं है!) –

5

प्रतिबिंब के उपयोग के बिना एक बाइट सरणी के लिए जाँच करने के लिए आप यह कर सकते हैं:

(def ^:const byte-array-type (type (byte-array 0))) 
(defn bytes? [x] (= (type x) byte-array-type)) 

बिल्कुल सही नहीं है क्यों, लेकिन आप ^:const के साथ बाइट-सरणी-प्रकार को भी रेखांकित कर सकते हैं।

2

अन्य सभी उत्तरों के लिए प्रॉप्स। यहाँ यह एक एक लाइनर प्रकार है:

(def byte-array? (partial instance? (Class/forName "[B"))) 

अन्य पुरातन के लिए, http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getName%28%29 (या जावा कल्पना) का संदर्भ लें। या सिर्फ जेरिट (type (xyz-array 0)) के साथ सुझाव देता है। विशेष रूप से आप का उपयोग कर सकते हैं:

"[Z" boolean array 
"[B" byte array 
"[C" char array 
"[D" double array 
"[F" float array 
"[I" integer array 
"[J" long array 
"[S" short array 

के बाद से प्रदर्शन का उल्लेख किया गया है, यहाँ (time (dotimes [_ 500000] (byte-array? x))) चलाने का एक छोटा सा बेंचमार्क परिणाम है, और byte-array-class साथ def'd

(def byte-array? (partial instance? (Class/forName "[B"))) 
78.518335 msecs 
(defn byte-array? [obj] (instance? byte-array-class obj)) 
34.879537 msecs 
(defn byte-array? [obj] (= (type obj) byte-array-class)) 
49.68781 msecs 

instance? बनाम type = उदाहरण? जीतता

partial बनाम defn = defn

जीतता है, लेकिन इन तरीकों में से किसी की संभावना नहीं प्रदर्शन में अड़चन हो जाएगा।