Изменение размера массива при сохранении текущих элементов в Java?

Я искал способ изменить размер массива в Java, но я не мог найти способы изменить размер массива при сохранении текущих элементов.

Я нашел, например, код типа int[] newImage = new int[newWidth];, но это удаляет элементы, сохраненные ранее.

мой код в принципе сделать это: если вы добавляете новый элемент, массив largens по 1. Я думаю, что это можно сделать с помощью динамического программирования, но я не уверен, как его реализовать.

11 ответов


вы не можете изменить размер массива в Java. Вам нужно либо:

  1. создать новый массив нужного размера и скопировать содержимое из исходного массива в новый массив, используя java.lang.System.arraycopy(...);

  2. использовать java.util.ArrayList<T> класс, который делает это для вас, когда вам нужно сделать массив больше. Он прекрасно инкапсулирует то, что вы описываете в своем вопросе.

  3. использовать java.util.Arrays.copyOf(...) методы, которые возвращают больший массив, с содержимое исходного массива.


Не хорошо, но работает:

    int[] a = {1, 2, 3};
    // make a one bigger
    a = Arrays.copyOf(a, a.length + 1);
    for (int i : a)
        System.out.println(i);

как указано выше, идите с ArrayList


вот несколько способов сделать это.


Способ 1: System.arrayCopy():

копирование массива из заданного исходного массива, начиная с указанной позиции в указанной позиции массива. Подпоследовательность компонентов массива копируется из исходного массива, на который ссылается src, в целевой массив, на который ссылается dest. Количество скопированных компонентов равно аргументу length. Компоненты на позиции srcPos через srcPos + length-1 в исходном массиве копируются в позиции destPos через destPos+length-1 соответственно целевого массива.

Object[] arr = new Object[5];
// initialize elements

Object[] largerArr = new Object[10];
System.arrayCopy(arr, 0, largerArr, 0, arr.length();

Способ 2: Arrays.copyOf():

копирует указанный массив, усекая или заполняя его нулями (при необходимости), чтобы копия имела указанную длину. Для всех индексов, допустимых как в исходном массиве, так и в копии, оба массива будут содержать одинаковые ценности. Для любых индексов, допустимых в копии, но не в оригинале, копия будет содержать null. Такие индексы будут существовать тогда и только тогда, когда указанная длина больше длины исходного массива. Результирующий массив имеет тот же класс, что и исходный массив.

Object[] arr = new Object[5];
// initialize elements

Object[] largerArr = Arrays.copyOf(arr, 10);

обратите внимание, что этот метод обычно использует System.arrayCopy() за кулисами.


Способ 3: ArrayList:

Resizable-реализация массива интерфейса списка. Выполняет все дополнительные операции списка, и разрешения все элементы, включая null. В дополнение к реализации интерфейса List этот класс предоставляет методы для управления размером массива, который используется внутри для хранения списка. (Этот класс примерно эквивалентен Vector, за исключением того, что он несинхронизирован.)

ArrayList функционирует аналогично массиву, за исключением того, что он автоматически расширяется при добавлении больше элементов, чем может содержать. Это поддерживается массивом и использует массивы.copyOf.

ArrayList<Object> list = new ArrayList<>();
// initialize elements

list.add(new Object());
// This will add the element, resizing the ArrayList if necassary.

вы можете просто использовать ArrayList который делает работу за вас.


вы можете использовать ArrayList вместо array. Так что вы можете добавить n количество элементов

 List<Integer> myVar = new ArrayList<Integer>();

стандартный класс java.утиль.ArrayList-это изменяемый массив, растущий при добавлении новых элементов.


изменить размер массива невозможно. Но вы можете скопировать элемент из одного массива в другой массив, создав массив большего размера.

рекомендуется создать массив двойного размера, если массив заполнен, и уменьшить массив вдвое, если массив заполнен наполовину

public class ResizingArrayStack1 {
    private String[] s;
    private int size = 0;
    private int index = 0;

    public void ResizingArrayStack1(int size) {
        this.size = size;
        s = new String[size];
    }


    public void push(String element) {
        if (index == s.length) {
            resize(2 * s.length);
        }
        s[index] = element;
        index++;
    }

    private void resize(int capacity) {
        String[] copy = new String[capacity];
        for (int i = 0; i < s.length; i++) {
            copy[i] = s[i];
            s = copy;
        }
    }

    public static void main(String[] args) {
        ResizingArrayStack1 rs = new ResizingArrayStack1();
        rs.push("a");
        rs.push("b");
        rs.push("c");
        rs.push("d");
    }
}

вы не можете изменить размер массива, но вы можете переопределить его, сохраняя старые значения или используя java.утиль.Список

здесь следует два решения, но поймать различия в производительности, выполняющие код ниже

списки Java в 450 раз быстрее, но в 20 раз тяжелее в памяти!

testAddByteToArray1 nanoAvg:970355051   memAvg:100000
testAddByteToList1  nanoAvg:1923106     memAvg:2026856
testAddByteToArray1 nanoAvg:919582271   memAvg:100000
testAddByteToList1  nanoAvg:1922660     memAvg:2026856
testAddByteToArray1 nanoAvg:917727475   memAvg:100000
testAddByteToList1  nanoAvg:1904896     memAvg:2026856
testAddByteToArray1 nanoAvg:918483397   memAvg:100000
testAddByteToList1  nanoAvg:1907243     memAvg:2026856
import java.util.ArrayList;
import java.util.List;

public class Test {

    public static byte[] byteArray = new byte[0];
    public static List<Byte> byteList = new ArrayList<>();
    public static List<Double> nanoAvg = new ArrayList<>();
    public static List<Double> memAvg = new ArrayList<>();

    public static void addByteToArray1() {
        // >>> SOLUTION ONE <<<
        byte[] a = new byte[byteArray.length + 1];
        System.arraycopy(byteArray, 0, a, 0, byteArray.length);
        byteArray = a;
        //byteArray = Arrays.copyOf(byteArray, byteArray.length + 1); // the same as System.arraycopy()
    }

    public static void addByteToList1() {
        // >>> SOLUTION TWO <<<
        byteList.add(new Byte((byte) 0));
    }

    public static void testAddByteToList1() throws InterruptedException {
        System.gc();
        long m1 = getMemory();
        long n1 = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            addByteToList1();
        }
        long n2 = System.nanoTime();
        System.gc();
        long m2 = getMemory();
        byteList = new ArrayList<>();
        nanoAvg.add(new Double(n2 - n1));
        memAvg.add(new Double(m2 - m1));
    }

    public static void testAddByteToArray1() throws InterruptedException {
        System.gc();
        long m1 = getMemory();
        long n1 = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            addByteToArray1();
        }
        long n2 = System.nanoTime();
        System.gc();
        long m2 = getMemory();
        byteArray = new byte[0];
        nanoAvg.add(new Double(n2 - n1));
        memAvg.add(new Double(m2 - m1));
    }

    public static void resetMem() {
        nanoAvg = new ArrayList<>();
        memAvg = new ArrayList<>();
    }

    public static Double getAvg(List<Double> dl) {
        double max = Collections.max(dl);
        double min = Collections.min(dl);
        double avg = 0;
        boolean found = false;
        for (Double aDouble : dl) {
            if (aDouble < max && aDouble > min) {
                if (avg == 0) {
                    avg = aDouble;
                } else {
                    avg = (avg + aDouble) / 2d;
                }
                found = true;
            }
        }
        if (!found) {
            return getPopularElement(dl);
        }
        return avg;
    }

    public static double getPopularElement(List<Double> a) {
        int count = 1, tempCount;
        double popular = a.get(0);
        double temp = 0;
        for (int i = 0; i < (a.size() - 1); i++) {
            temp = a.get(i);
            tempCount = 0;
            for (int j = 1; j < a.size(); j++) {
                if (temp == a.get(j))
                    tempCount++;
            }
            if (tempCount > count) {
                popular = temp;
                count = tempCount;
            }
        }
        return popular;
    }

    public static void testCompare() throws InterruptedException {
        for (int j = 0; j < 4; j++) {
            for (int i = 0; i < 20; i++) {
                testAddByteToArray1();
            }
            System.out.println("testAddByteToArray1\tnanoAvg:" + getAvg(nanoAvg).longValue() + "\tmemAvg:" + getAvg(memAvg).longValue());
            resetMem();
            for (int i = 0; i < 20; i++) {
                testAddByteToList1();
            }
            System.out.println("testAddByteToList1\tnanoAvg:" + getAvg(nanoAvg).longValue() + "\t\tmemAvg:" + getAvg(memAvg).longValue());
            resetMem();
        }
    }

    private static long getMemory() {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }

    public static void main(String[] args) throws InterruptedException {
        testCompare();
    }
}

изменить размер массива невозможно. Однако можно изменить размер массива путем копирования исходного массива на новый размер и сохранить текущие элементы. Массив также может быть уменьшен в размере путем удаления элемента и изменения размера.

import java.util.Arrays 
public class ResizingArray {

    public static void main(String[] args) {

        String[] stringArray = new String[2] //A string array with 2 strings 
        stringArray[0] = "string1";
        stringArray[1] = "string2";

        // increase size and add string to array by copying to a temporary array
        String[] tempStringArray = Arrays.copyOf(stringArray, stringArray.length + 1);
        // Add in the new string 
        tempStringArray[2] = "string3";
        // Copy temp array to original array
        stringArray = tempStringArray;

       // decrease size by removing certain string from array (string1 for example)
       for(int i = 0; i < stringArray.length; i++) {
           if(stringArray[i] == string1) {
               stringArray[i] = stringArray[stringArray.length - 1];
               // This replaces the string to be removed with the last string in the array
               // When the array is resized by -1, The last string is removed 
               // Which is why we copied the last string to the position of the string we wanted to remove
               String[] tempStringArray2 = Arrays.copyOf(arrayString, arrayString.length - 1);
                // Set the original array to the new array
               stringArray = tempStringArray2;
           }
       }
    }    
}

вы можете попробовать ниже решение внутри некоторого класса:

int[] a = {10, 20, 30, 40, 50, 61};

// private visibility - or change it as needed
private void resizeArray(int newLength) {
    a = Arrays.copyOf(a, a.length + newLength);
    System.out.println("New length: " + a.length);
}

Извините, но в это время невозможно изменить размер массивов и, возможно, никогда не будет.

поэтому моя рекомендация -думаю, что больше чтобы найти решение, которое позволит вам получить с самого начала процесса, размер массивов, которые вы будете requiere. Это часто подразумевает, что вашему коду нужно немного больше времени (строк) для запуска, но вы сэкономите много ресурсов памяти.