2010-07-25 32 views

risposta

69

Si potrebbe provare System.arraycopy o utilizzare le funzioni di matrice nella classe Arrays come java.util.Arrays.copyOf. Entrambi dovrebbero darti prestazioni natali sotto il cofano.

Arrays.copyOf è probabilmente favorevole per la leggibilità, ma è stato introdotto solo in java 1.6.

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

Penso che la seconda opzione sia più "logica". Non ho mai capito perché System.arraycopy() è dove si trova, una delle posizioni più clamorose possibili. – sinuhepop

+0

@Sinuhe: è lì per ragioni storiche. –

+12

Questa NON è la risposta corretta. memcpy() non assegna dati, ma solo copie a un buffer esistente. Mentre Arrays.copyOf() alloca chiaramente nuova memoria. – splinux

5

È possibile utilizzare System.arrayCopy. Copia elementi da una matrice sorgente a una matrice di destinazione. L'implementazione di Sun utilizza un assemblatore ottimizzato a mano, quindi è veloce.

78

Uso System.arraycopy()

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

Esempio,

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


oppure usa Arrays.copyOf()
Esempio,

target = Arrays.copyOf(source, length); 

java.util.Arrays.copyOf(byte[] source, int length) è stato aggiunto in JDK 1.6.

Il metodo copyOf() utilizza System.arrayCopy() per creare una copia dell'array, ma è più flessibile di clone() poiché è possibile eseguire copie di parti di un array.

+0

+1 per gli esempi. –

+0

Arrays.copyOf() assegna anche memoria. nel tuo esempio se cambi String [] target = new String [4]; e quindi target = Arrays.copyOf() crea un nuovo target che è una stringa [3]. Non il comportamento memcopy. – MikeF

7

Se si desidera solo una copia esatta di un array monodimensionale, utilizzare clone().

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

Per altre operazioni di copia matrice, utilizzare System.arrayCopy/Arrays.copyOf come Tom suggests.

In generale, è consigliabile evitare clone, ma questa è un'eccezione alla regola.

+0

Vedi anche maggiori dettagli nella risposta accettata a http://stackoverflow.com/questions/3208899/how-do-i-clone-a-java-byte-array. –

2

Java ha effettivamente qualcosa come memcpy(). La classe Unsafe ha un metodo copyMemory() che è essenzialmente identico a memcpy(). Ovviamente, come memcpy(), non fornisce alcuna protezione dalle sovrapposizioni di memoria, dalla distruzione dei dati, ecc. Non è chiaro se sia realmente un memcpy() o un memmove(). Può essere utilizzato per copiare da indirizzi reali a indirizzi reali o da riferimenti a riferimenti. Si noti che se vengono utilizzati riferimenti, è necessario fornire un offset (o la JVM morirà APPENA POSSIBILE).

Unsafe.copyMemory() funziona (fino a 2 GB al secondo sul mio vecchio PC stanco). Utilizzare a proprio rischio. Si noti che la classe Unsafe non esiste per tutte le implementazioni JVM.

+0

scusa per aver fatto il seminario su questo thread antico, ma potresti darmi un esempio su come farlo con una serie di riferimenti. Ed è più veloce per piccole quantità di dati (come 1-4 MB) o semplicemente degno in caso di dati più grandi come il 2GB che hai citato? – FinnTheHuman

+0

L'uso della classe 'sun.misc.Unsafe' è considerata una cattiva pratica" hack "b/c è una classe di pacchetto * private *. Inoltre, a partire da Java 9, non sarà più disponibile, quindi provare a utilizzare questa classe equivale a chiedere l'interruzione imprevista del codice. – ray

Problemi correlati