tags:

views:

993

answers:

5

In Java, is there a way to truncate an array without having to make a copy of it? The common idiom is Arrays.copyOf(foo, n) (where the new array is n elements long). I don't think there is an alternative, but I'm curious as to whether there is a better approach.

+4  A: 

An array's length in Java cannot be altered after initialization, so you're forced to make a copy with the new size. Actually, the length parameter of a Java array is actually declared as final, so it cannot be changed once it's set.

If you need to change an array's size, I'd use an ArrayList.

AlbertoPL
+1, Arraylists are very nice if you're trying to manipulate the size of things or remove elements efficiently.
Brian
A: 

I don't believe so. An array is allocated as a contiguous block of memory, and I can't imagine that there is any way of releasing a part of that block.

David Johnstone
A: 

No way. You could story somewhere the truncated lenth but it would not be the value returned by array.length.

Use an Arraylist instead.

Burkhard
A: 

Rob,

Succinctly: No, There isn't, as far as I know. A Java array is a fixed-size data-structure. The only way to "logically" resize it is create a new array and copy the wanted elements into the new aray.

Instead: You could (possibly) implement a class which wraps an array into a collection and uses a "size" variable to logically reduce the length of the array without actually copying the values. This an approach has limited utility... The only case I can imagine where it's practical is when you're dealing with a huge array, which just can't be copied because of memory limitations.

Copying an array is relatively inexpensive time-wise... unless you're doing it millions of times, in which case you probably need to think up an algorithm to avoid this, and not waste your time mucking around with a "variable length array".

And of course... you could just use an ArrayList instead. Yes?

Cheers. Keith.

corlettk
A: 

I was thinking about it some more... and just for kicks, how about something like the below.

Note: This is just a "can it be done?" intellectual exercise in Java hacking. Anybody who attempts to actually use this idea in production code will deserve all the pain that will undoubtedly follow.

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);
    }
}
Rob