Подтвердить что ты не робот

Усекать массив без копирования?

В Java есть способ обрезать массив без необходимости его копии? Общая идиома Arrays.copyOf(foo, n) (где новый массив - n элементов). Я не думаю, что есть альтернатива, но мне любопытно, есть ли лучший подход.

4b9b3361

Ответ 1

Длина массива в Java не может быть изменена после инициализации, поэтому вы вынуждены сделать копию с новым размером. Фактически параметр длины массива Java объявляется окончательным, поэтому он не может быть изменен после его установки.

Если вам нужно изменить размер массива, я бы использовал ArrayList.

Ответ 2

Я думал об этом еще... и просто для пинков, как о чем-то вроде ниже.

Примечание: Это просто "можно ли это сделать?" интеллектуальные упражнения в Java-хаке. Любой, кто пытается использовать эту идею в производственном кодексе, заслуживает всей боли, которая, несомненно, последует.

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 gotta be a way though!
        unsafe.reallocateMemory(ptr, 5);
        System.out.println("New array size is: " + array.length);
    }
}

Ответ 3

Я так не верю. Массив выделяется как непрерывный блок памяти, и я не могу себе представить, что есть какой-либо способ освобождения части этого блока.

Ответ 4

Кратко: Нет, нет, насколько я знаю. Массив Java - это структура данных фиксированного размера. Единственный способ "изменить логически" это создать новый массив и скопировать нужные элементы в новый массив.

Вместо этого: вы можете (возможно) реализовать класс, который обертывает массив в коллекцию и использует переменную "размер" для логического сокращения длины массива без фактического копирования значений. Этот подход имеет ограниченную полезность... Единственный случай, я могу себе представить, где это практично, когда вы имеете дело с огромным массивом, который просто не может быть скопирован из-за ограничений памяти.

Копирование массива относительно недорого по времени... если вы не делаете это миллионы раз, и в этом случае вам, вероятно, нужно придумать алгоритм, чтобы избежать этого, а не тратить время на то, массив переменной длины ".

И конечно... вы могли бы просто использовать ArrayList. Да?