2009-07-02 12 views
24

En Java, ¿hay alguna manera de truncar una matriz sin tener que hacer una copia? La expresión común es Arrays.copyOf(foo, n) (donde la nueva matriz tiene n elementos largos). No creo que haya una alternativa, pero tengo curiosidad sobre si hay un mejor enfoque.Truncar una matriz sin copiarla?

Respuesta

19

La longitud de una matriz en Java no se puede modificar después de la inicialización, por lo que debe hacer una copia con el nuevo tamaño. En realidad, el parámetro de longitud de una matriz de Java se declara como final, por lo que no se puede cambiar una vez que se ha establecido.

Si necesita cambiar el tamaño de una matriz, usaría una ArrayList.

+1

+1, Las listas de arreglos son muy buenas si está intentando manipular el tamaño de las cosas o eliminar elementos de manera eficiente. – Brian

0

No lo creo. Una matriz se asigna como un bloque contiguo de memoria, y no puedo imaginar que haya alguna forma de liberar una parte de ese bloque.

0

Sucintamente: No, no hay, hasta donde yo sé. Una matriz de Java es una estructura de datos de tamaño fijo. La única forma de redimensionarlo "lógicamente" es crear una nueva matriz y copiar los elementos deseados en la nueva matriz.

En su lugar: podría (posiblemente) implementar una clase que envuelve una matriz en una colección y utiliza una variable de "tamaño" para reducir lógicamente la longitud de la matriz sin copiar los valores. Este enfoque tiene una utilidad limitada ... El único caso que puedo imaginar donde es práctico es cuando se trata de una matriz enorme, que simplemente no se puede copiar debido a limitaciones de memoria.

Copiar una matriz es relativamente económico en cuanto al tiempo ... a menos que lo haga millones de veces, en cuyo caso probablemente necesite idear un algoritmo para evitarlo y no perder el tiempo con un "matriz de longitud variable".

Y, por supuesto ... en su lugar, podría usar una ArrayList. ¿Sí?

5

Estaba pensando en ello un poco más ... y solo por diversión, ¿qué tal algo así como a continuación?

Nota: Esto es solo un "¿se puede hacer?" ejercicio intelectual en hacking de Java. Cualquiera que intente realmente usar esta idea en el código de producción se merecerá todo el dolor que indudablemente seguirá.

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); 
    } 
} 
Cuestiones relacionadas