2009-07-02 9 views
24

In Java, c'è un modo per troncare un array senza doverne fare una copia? L'idioma comune è Arrays.copyOf(foo, n) (dove il nuovo array è n elementi lunghi). Non penso ci sia un'alternativa, ma sono curioso di sapere se esiste un approccio migliore.Tronca un array senza copiarlo?

risposta

19

La lunghezza di una matrice in Java non può essere modificata dopo l'inizializzazione, quindi è necessario eseguire una copia con la nuova dimensione. In realtà, il parametro length di un array Java viene dichiarato come finale, quindi non può essere modificato una volta impostato.

Se è necessario modificare le dimensioni di un array, utilizzare ArrayList.

+1

+1, Gli arraylists sono molto carini se si sta tentando di manipolare la dimensione delle cose o rimuovere gli elementi in modo efficiente. – Brian

0

Non ci credo. Un array viene allocato come un blocco contiguo di memoria e non riesco a immaginare che esista un modo per rilasciare una parte di quel blocco.

0

succintamente: No, non c'è, per quanto ne so. Un array Java è una struttura dati a dimensione fissa. L'unico modo per ridimensionare "logicamente" è creare un nuovo array e copiare gli elementi ricercati nel nuovo array.

Invece: è possibile (eventualmente) implementare una classe che avvolge una matrice in una raccolta e utilizza una variabile "dimensione" per ridurre logicamente la lunghezza della matrice senza effettivamente copiare i valori. Questo approccio ha un'utilità limitata ... L'unico caso in cui riesco a immaginare dove sia pratico è quando si ha a che fare con un enorme array, che non può essere copiato a causa dei limiti di memoria.

La copia di un array è relativamente poco dispendiosa in termini di tempo ... a meno che non lo facciate milioni di volte, nel qual caso probabilmente è necessario pensare a un algoritmo per evitarlo, e non sprecare il vostro tempo ad andare in giro con un "array a lunghezza variabile".

E ovviamente ... si può semplicemente usare un ArrayList. Sì?

5

Ci stavo pensando un po 'di più ... e solo per i calci, che ne dici di qualcosa come il sotto.

Nota: Questo è solo un "può essere fatto?" esercizio intellettuale nell'hacking di Java. Chiunque tenti di utilizzare effettivamente questa idea nel codice di produzione meriterà tutto il dolore che seguirà senza dubbio.

public class Foo 
{ 
    private static byte[] array = new byte[10]; 

    public static void main(String[] arg) throws Exception 
    { 
     Field field = Unsafe.class.getDeclaredField("theUnsafe"); 
     field.setAccessible(true); 
     Unsafe unsafe = (Unsafe) field.get(null); 
     Field arrayField = Foo.class.getDeclaredField("array"); 
     long ptr = unsafe.staticFieldOffset(arrayField); 
     // doesn't work... there's gotta be a way though! 
     unsafe.reallocateMemory(ptr, 5); 
     System.out.println("New array size is: " + array.length); 
    } 
} 
Problemi correlati