Ho una libreria di classi, che lavora con i miei dati, che vengono letti nel buffer. È possibile in qualche modo evitare di copiare gli array più e più volte, passando parti di dati sempre più in profondità nei metodi di elaborazione? Beh, suona strano, ma nel mio caso particolare, c'è uno scrittore speciale, che divide i dati in blocchi e li scrive individualmente in posizioni diverse, quindi esegue semplicemente System.arraycopy, ottiene ciò di cui ha bisogno e chiama lo scrittore sottostante, con quello nuovo sottoarray. E questo succede molte volte. Qual è l'approccio migliore per refactoring di tale codice?Come ottenere un sotto array di array in Java, senza copiare i dati?
risposta
Molte classi in Java accettano un sottoinsieme di un array come parametro. Per esempio. Writer.write (char cbuf [], int off, int len). Forse questo è già sufficiente per il tuo caso.
Questo è l'approccio più semplice, quindi proverò. –
avere uno sguardo su Arrays.copyOfRange(***)
metodi.
Da javadoc: "Copia l'intervallo specificato dell'array specificato in un nuovo array", che non è ciò che l'OP desidera. – f1sh
Si potrebbe prendere lo stesso approccio della classe String
prende; creare una classe per oggetti immutabili che sono costruiti da una matrice, un offset iniziale e uno sfasamento finale che offre l'accesso alla matrice secondaria. L'utente di un tale oggetto non deve conoscere la distinzione tra l'intero array o un sotto-array. Il costruttore non deve copiare la matrice, ma solo il riferimento dell'array e i suoi limiti.
Arrays.asList(array).subList(x, y).
Questo metodo non ti dà un array, ma un List
, che è molto più flessibile.
Si potrebbe utilizzare (ArrayList) .subList (valore1, valore2) i belive, forse, che potrebbe aiutare nel vostro caso? Ovviamente, se vuoi usare un ArrayList.
questa risposta non è stata già fornita? – dldnh
Non esiste un modo reale per avvolgere qualsiasi dato senza copiare e ricevere arra reale in Java. Non puoi semplicemente creare un nuovo array sulla memoria esistente. Hai fondamentalmente 2 opzioni:
- Utilizzare metodi che possono accettare gamma di matrice. Questo era già raccomandato.
- Utilizzare il wrapper che offre una sorta di astrazione vicina all'array ed è adatta a molte applicazioni. Sarà descritto di seguito.
Puoi svolgere gerarchia java.nio.Buffer
classi, specialmente java.nio.ByteBuffer
che offre tampone astrazione su tutta la matrice o sottointervalli. Spesso è ciò di cui le persone hanno bisogno. Questo offre anche molte abilità interessanti come il capovolgimento "zero copy" e la rappresentazione dell'area di byte flessibile.
Ecco esempio di confezionamento utilizzando java.nio.ByteBuffer
. Questo dovrebbe essere molto vicino a quello che ti serve. Almeno per alcune operazioni.
byte [] a1 = {0, 0, 1, 0};
ByteBuffer buf = ByteBuffer.wrap(a1,1,2);
Poi si può fare su qualsiasi buf
ByteBuffer
operazione.
Solo un avviso, buf.array()
restituisce l'originale a1
array (backend) con tutti gli elementi.
Ah quindi anche se faccio buf = ByteBuffer.wrap (a1, 1, 2) ... buf.array() restituirà ancora {0, 0, 1, 0}. Quindi questa idea non può essere davvero utilizzata per ottenere un sottoarray? – Benitok
Non è possibile ottenere una vera sottoarray senza copiare in Java. Quindi vengono utilizzati wrapper. L'elenco uno è stato illustrato prima e l'astrazione Buffer è un altro. Direi che è molto più utile sulla gamma di byte della memoria, ma per gli array di oggetti complessi. L'elenco è più comune. –
Non esiste alcun modo per dichiarare un sottoarray in Java se si utilizzano gli array incorporati come byte []. Il motivo è: la lunghezza dell'array è memorizzata con i dati, non con la dichiarazione del riferimento ad esso. Quindi un sottoarray che non copia i dati non ha posto dove può memorizzare la lunghezza! Quindi per i tipi di base è possibile utilizzare le copie di array di byte efficienti menzionate e per i tipi superiori (List) ci sono metodi disponibili.
Che ne dici di fare qualche magia JNI in C++? Potrebbe essere un disastro dal GC POV. –
possibile duplicato di [Afferra un segmento di un array in Java senza creare un nuovo array su heap] (http://stackoverflow.com/questions/1100371/grab-a-segment-of-an-array-in-java- senza-creare-un-nuovo-array-on-heap) –