क्या जावा में मेम्ची () के बराबर है?


83

मेरे पास एक बाइट है [] और इसे एक अन्य बाइट [] में कॉपी करना चाहेंगे। शायद मैं अपनी सरल 'सी' पृष्ठभूमि यहां दिखा रहा हूं, लेकिन क्या जावा में बाइट सरणियों के बराबर मेम्ची () के बराबर है?

जवाबों:


86

आप कक्षा System.arraycopyमें सरणी फ़ंक्शंस का उपयोग या प्रयास कर सकते हैं । दोनों को आपको हुड के तहत मूल प्रदर्शन देना चाहिए।Arraysjava.util.Arrays.copyOf

Arrays.copyOf संभवतः पठनीयता के लिए अनुकूल है, लेकिन केवल जावा 1.6 में पेश किया गया था।

 byte[] src = {1, 2, 3, 4};
 byte[] dst = Arrays.copyOf(src, src.length);
 System.out.println(Arrays.toString(dst));

मुझे लगता है कि दूसरा विकल्प अधिक "तार्किक" है। मुझे कभी समझ में नहीं आया कि क्यों System.arraycopy () वह जगह है, जहां एक सबसे अधिक संभव स्थानों में से एक है।
sinuhepop

@ सिनुहे - यह ऐतिहासिक कारणों से है।
स्टीफन सी।

30
यह सही उत्तर नहीं है। memcpy () डेटा को आवंटित नहीं करता है, केवल मौजूदा बफर को कॉपी करता है। जबकि Arrays.copyOf () स्पष्ट रूप से नई मेमोरी आवंटित करता है।

105

उपयोग System.arraycopy () का करें

System.arraycopy(sourceArray, 
                 sourceStartIndex,
                 targetArray,
                 targetStartIndex,
                 length);

उदाहरण,

String[] source = { "alpha", "beta", "gamma" };
String[] target = new String[source.length];
System.arraycopy(source, 0, target, 0, source.length);


या Arrays.copyOf () का उपयोग करें
उदाहरण का ,

target = Arrays.copyOf(source, length);

java.util.Arrays.copyOf(byte[] source, int length)JDK 1.6 में जोड़ा गया था। विधि का उपयोग करता सरणी की एक प्रतिलिपि बनाने के लिए, लेकिन से अधिक लचीला है जब से तुम एक सरणी के कुछ हिस्सों की प्रतियां बना सकते हैं।

copyOf()System.arrayCopy()clone()


5
Arrays.copyOf () भी मेमोरी आवंटित करता है। अपने उदाहरण में यदि आप स्ट्रिंग बदलते हैं [] लक्ष्य = नया स्ट्रिंग [4]; और फिर लक्ष्य = Arrays.copyOf () यह एक नया लक्ष्य बनाता है जो एक स्ट्रिंग [3] है। संस्मरण व्यवहार नहीं।
माइकएफ

Arrays.copyOf आंतरिक रूप से System.arraycopy का उपयोग करता है जो एक देशी विधि है।
गजराज तंवर

10

यदि आप केवल एक-आयामी सरणी की एक सटीक प्रतिलिपि चाहते हैं, तो उपयोग करें clone()

byte[] array = { 0x0A, 0x01 };
byte[] copy = array.clone();

अन्य सरणी प्रतिलिपि कार्यों के लिए, टॉम सुझाव के रूप में उपयोग System.arrayCopy/ Arrays.copyOfकरता है

सामान्य तौर पर, cloneइससे बचना चाहिए, लेकिन यह नियम का अपवाद है।


स्वीकार किए जाते हैं जवाब देने के लिए में भी अधिक विवरण देखने के stackoverflow.com/questions/3208899/...
एंडी थॉमस

5

आप System.arrayCopy का उपयोग कर सकते हैं । यह स्रोत सरणी से गंतव्य सरणी तक तत्वों को कॉपी करता है। सूर्य कार्यान्वयन हाथ से अनुकूलित कोडांतरक का उपयोग करता है, इसलिए यह तेज है।


3

वास्तव में जावा में मेमसीपी () जैसा कुछ है। Unsafe क्लास में एक copyMemory () विधि है जो अनिवार्य रूप से memcpy () के समान है। बेशक, मेम्कपी () की तरह, यह मेमोरी ओवरले, डेटा विनाश आदि से कोई सुरक्षा प्रदान नहीं करता है, यह स्पष्ट नहीं है कि क्या यह वास्तव में एक मेमसीपी () या एक मेमोव () है। इसका उपयोग वास्तविक पते से वास्तविक पते या संदर्भ से संदर्भ की प्रतिलिपि बनाने के लिए किया जा सकता है। ध्यान दें कि यदि संदर्भ का उपयोग किया जाता है, तो आपको एक ऑफसेट प्रदान करना होगा (या JVM ASAP मर जाएगा)।

Unsafe.copyMemory () मेरे पुराने थके हुए पीसी पर (प्रति सेकंड 2 जीबी तक) काम करता है। अपने जोखिम पार इस्तेमाल करें। ध्यान दें कि सभी जेवीएम कार्यान्वयन के लिए असुरक्षित वर्ग मौजूद नहीं है।


इस प्राचीन सूत्र पर सभी पालतू साहित्यिकों को जाने के लिए खेद है, लेकिन क्या आप मुझे उदाहरण के संदर्भ में ऐसा करने के बारे में एक उदाहरण दे सकते हैं। और क्या यह छोटी मात्रा में डेटा (जैसे 1-4 एमबी) या सिर्फ 2GB जैसे बड़े डेटा के मामले में योग्य है?
फिन हनुमान

2
sun.misc.Unsafeकक्षा का उपयोग करना एक बुरा अभ्यास माना जाता है "हैक" बी / सी यह एक निजी पैकेज वर्ग है। इसके अलावा, जावा 9 में शुरू, यह अब उपलब्ध नहीं होगा, इसलिए इस वर्ग का उपयोग करने की कोशिश करना आपके कोड को अप्रत्याशित रूप से तोड़ने के लिए भीख माँगने के समान है।
code_dredd


2

जब आप JDK 1.5+ का उपयोग कर रहे हैं तो आपको उपयोग करना चाहिए

System.arraycopy()

के बजाय

Arrays.copyOfRange()

Beacuse Arrays.copyOfRange () JDK 1.6 तक जोड़ा नहीं गया था। आप प्राप्त कर सकते हैं

Java - “Cannot Find Symbol” error

JDK के उस संस्करण में Arrays.copyOfRange को कॉल करते समय।


0

ByteBufferViewVarHandle का उपयोग करें या byteArrayViewVarHandle का ।

यह आपको "लॉन्ग" की एक सरणी को सीधे "डबल्स" की एक सरणी में कॉपी करने देगा और कुछ इस तरह के साथ:

public long[] toLongs(byte[] buf) {
    int end = buf.length >> 3;
    long[] newArray = new long[end];
    for (int ii = 0; ii < end; ++ii) {
        newArray[ii] = (long)AS_LONGS_VH.get(buf, ALIGN_OFFSET + ii << 3);
    }
}

private static final ALIGN_OFFSET = ByteBuffer.wrap(new byte[0]).alignmentOffset(8); 
private static final VarHandle AS_LONGS_VH = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.nativeOrder());

यह आपको थोड़ी हैकिंग करने देगा जैसे:

float thefloat = 0.4;
int floatBits;
_Static_assert(sizeof theFloat == sizeof floatBits, "this bit twiddling hack requires floats to be equal in size to ints");
memcpy(&floatBits, &thefloat, sizeof floatBits);

0

नहीं। जावा के बराबर नहीं है memcpy। जावा के memmoveबजाय इसके बराबर है ।

यदि src और डेस्ट तर्क समान सरणी ऑब्जेक्ट को संदर्भित करते हैं, तो प्रतिलिपि बनाई जाती है जैसे कि srcPos + length-1 के माध्यम से पदों पर घटकों को पहले लंबाई के घटकों के साथ एक अस्थायी सरणी में कॉपी किया गया था और फिर अस्थायी सरणी की सामग्री थी गंतव्य सरणी के destPos + लंबाई -1 के माध्यम से नियत स्थानों में कॉपी किया जाता है।

ओरेकल डॉक्स

यह बहुत संभव System.arraycopyहै कि उसी तरह का प्रदर्शन कभी नहीं होगा जैसे memcpyकि srcऔर destउसी सरणी को देखें। आमतौर पर यह काफी तेज होगा, हालांकि।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.